feat(gstack2): consolidated runtime — execution-result contract, profiles, capability readiness, hardening (#10)

feat(gstack2): consolidated runtime — execution-result contract, profiles, capability readiness, hardening
This commit is contained in:
Time Attakc
2026-07-21 14:41:32 -07:00
committed by GitHub
69 changed files with 3583 additions and 3363 deletions
+1 -1
View File
@@ -49,5 +49,5 @@ bin/* text eol=lf
# The committed diagram-render bundle is hash-pinned (BUILD_INFO sha256); # The committed diagram-render bundle is hash-pinned (BUILD_INFO sha256);
# a CRLF rewrite on Windows checkout would break the drift test and change # a CRLF rewrite on Windows checkout would break the drift test and change
# the content-addressed staged filename. # the content-addressed staged filename.
lib/diagram-render/dist/*.html text eol=lf lib/diagram-render/dist/*.html text eol=lf whitespace=-trailing-space
lib/diagram-render/dist/*.json text eol=lf lib/diagram-render/dist/*.json text eol=lf
+4
View File
@@ -4,6 +4,10 @@ on: [push, pull_request]
permissions: permissions:
contents: read contents: read
concurrency:
group: actionlint-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
actionlint: actionlint:
runs-on: ubicloud-standard-8 runs-on: ubicloud-standard-8
+4
View File
@@ -16,6 +16,10 @@ on:
# Manual trigger # Manual trigger
workflow_dispatch: workflow_dispatch:
concurrency:
group: ci-image
cancel-in-progress: false
jobs: jobs:
build: build:
runs-on: ubicloud-standard-8 runs-on: ubicloud-standard-8
+21
View File
@@ -0,0 +1,21 @@
name: Dependency Review
on:
pull_request:
branches: [main]
permissions:
contents: read
concurrency:
group: dependency-review-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
dependency-review:
runs-on: ubuntu-24.04
steps:
- name: Review dependency changes
uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
with:
fail-on-severity: high
+26
View File
@@ -0,0 +1,26 @@
name: OSV Scanner
on:
schedule:
- cron: '23 7 * * 1'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: osv-scanner
cancel-in-progress: true
jobs:
scan:
permissions:
actions: read
contents: read
security-events: write
uses: google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@3adb4b14a2b0623876d18d863a498b785fb3752d # v2.3.8
with:
scan-args: |-
--include-git-root
--recursive
./
+4
View File
@@ -10,6 +10,10 @@ on:
permissions: permissions:
contents: read contents: read
concurrency:
group: quality-gate-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
quality: quality:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
+46
View File
@@ -0,0 +1,46 @@
name: OpenSSF Scorecard
on:
branch_protection_rule:
schedule:
- cron: '41 7 * * 1'
push:
branches: [main]
permissions:
contents: read
concurrency:
group: scorecard-${{ github.ref }}
cancel-in-progress: true
jobs:
analysis:
runs-on: ubuntu-24.04
permissions:
contents: read
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Run Scorecard analysis
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
with:
results_file: results.sarif
results_format: sarif
publish_results: false
- name: Upload Scorecard results to code scanning
uses: github/codeql-action/upload-sarif@85b88275909735f5bc23196090e03d2eb148b3de # v3.32.4
with:
sarif_file: results.sarif
- name: Upload Scorecard results artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: scorecard-results
path: results.sarif
retention-days: 5
+4
View File
@@ -4,6 +4,10 @@ on: [push, pull_request]
permissions: permissions:
contents: read contents: read
concurrency:
group: skill-docs-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
check-freshness: check-freshness:
runs-on: ubicloud-standard-8 runs-on: ubicloud-standard-8
+15
View File
@@ -0,0 +1,15 @@
# OSV-Scanner configuration.
# Direct/transitive dependency versions are pinned to their fixed releases via
# the `overrides` block in package.json; this file only records advisories we
# have assessed as not-reachable or not-fixable without disproportionate risk.
[[IgnoredVulns]]
id = "GHSA-frvp-7c67-39w9"
# @hono/node-server 1.19.x. Reachable only through @modelcontextprotocol/sdk,
# which is an unused transitive dependency (no source file imports it) and never
# starts a Hono HTTP server, so the advisory's request path is not exercised.
# The only fix is @hono/node-server 2.0.5, a major bump the MCP SDK pins against
# (^1.19.9); forcing it via override risks breaking the SDK at runtime for a
# vulnerability we do not expose. Re-evaluate if the MCP SDK becomes a direct,
# server-hosting dependency.
reason = "Unreachable transitive (unused @modelcontextprotocol/sdk); fix requires a risky major override on a pinned peer dep."
+6 -2
View File
@@ -611,8 +611,12 @@ Data is stored in [Supabase](https://supabase.com) (open source Firebase alterna
## Troubleshooting ## Troubleshooting
For GStack 2, first run `gstack doctor` (or `gstack doctor --json`) when the For GStack 2, run `gstack doctor --capability browser|design|diagram|pdf|ios`
optional runtime is installed. For skill discovery problems, use the standard (optionally `--json`) for a focused, non-mutating readiness result. It reports
pure-judgment availability, platform support, preview consent, install consent,
and runtime readiness separately; see
[`docs/gstack-2/CAPABILITY-READINESS.md`](docs/gstack-2/CAPABILITY-READINESS.md).
For skill discovery problems, use the standard
installer's list and reinstall commands; do not manually copy host paths. The installer's list and reinstall commands; do not manually copy host paths. The
entries below apply to legacy 1.x installations. entries below apply to legacy 1.x installations.
+8 -4
View File
@@ -118,10 +118,14 @@ describe('validateTempPath', () => {
expect(() => validateTempPath('/tmp/nonexistent-file-12345.jpg')).toThrow(/not found/i); expect(() => validateTempPath('/tmp/nonexistent-file-12345.jpg')).toThrow(/not found/i);
}); });
it('rejects paths in cwd', () => { it('rejects a temp-directory symlink that resolves outside temp', () => {
// Create a real file in cwd to test the path check (not the existence check) const link = path.join(TEMP_DIR, `test-temp-link-${Date.now()}`);
const cwdFile = path.join(process.cwd(), 'package.json'); fs.symlinkSync('/etc/passwd', link);
expect(() => validateTempPath(cwdFile)).toThrow(/temp directory/i); try {
expect(() => validateTempPath(link)).toThrow(/temp directory/i);
} finally {
fs.unlinkSync(link);
}
}); });
it('rejects absolute paths outside safe dirs', () => { it('rejects absolute paths outside safe dirs', () => {
+64 -492
View File
@@ -1,25 +1,29 @@
/** /** Tests for the retired passive updater and its explicit compatibility check. */
* Tests for bin/gstack-update-check bash script.
*
* Uses Bun.spawnSync to invoke the script with temp dirs and
* GSTACK_DIR / GSTACK_STATE_DIR / GSTACK_REMOTE_URL env overrides
* for full isolation.
*/
import { describe, test, expect, beforeEach, afterEach } from 'bun:test'; import { afterEach, beforeEach, describe, expect, test } from 'bun:test';
import { mkdtempSync, writeFileSync, rmSync, existsSync, readFileSync, mkdirSync, symlinkSync, utimesSync } from 'fs'; import {
import { join } from 'path'; existsSync,
import { tmpdir } from 'os'; mkdirSync,
mkdtempSync,
readFileSync,
rmSync,
symlinkSync,
writeFileSync,
} from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
const SCRIPT = join(import.meta.dir, '..', '..', 'bin', 'gstack-update-check'); const ROOT = join(import.meta.dir, '..', '..');
const SCRIPT = join(ROOT, 'bin', 'gstack-update-check');
let gstackDir: string; let gstackDir: string;
let stateDir: string; let stateDir: string;
function run(extraEnv: Record<string, string> = {}, args: string[] = []) { function run(args: string[] = [], extraEnv: Record<string, string> = {}) {
const result = Bun.spawnSync(['bash', SCRIPT, ...args], { const result = Bun.spawnSync(['bash', SCRIPT, ...args], {
env: { env: {
...process.env, ...process.env,
GSTACK_HOME: '',
GSTACK_DIR: gstackDir, GSTACK_DIR: gstackDir,
GSTACK_STATE_DIR: stateDir, GSTACK_STATE_DIR: stateDir,
GSTACK_REMOTE_URL: `file://${join(gstackDir, 'REMOTE_VERSION')}`, GSTACK_REMOTE_URL: `file://${join(gstackDir, 'REMOTE_VERSION')}`,
@@ -38,10 +42,9 @@ function run(extraEnv: Record<string, string> = {}, args: string[] = []) {
beforeEach(() => { beforeEach(() => {
gstackDir = mkdtempSync(join(tmpdir(), 'gstack-upd-test-')); gstackDir = mkdtempSync(join(tmpdir(), 'gstack-upd-test-'));
stateDir = mkdtempSync(join(tmpdir(), 'gstack-state-test-')); stateDir = mkdtempSync(join(tmpdir(), 'gstack-state-test-'));
// Link real gstack-config so update_check config check works
const binDir = join(gstackDir, 'bin'); const binDir = join(gstackDir, 'bin');
mkdirSync(binDir); mkdirSync(binDir);
symlinkSync(join(import.meta.dir, '..', '..', 'bin', 'gstack-config'), join(binDir, 'gstack-config')); symlinkSync(join(ROOT, 'bin', 'gstack-config'), join(binDir, 'gstack-config'));
}); });
afterEach(() => { afterEach(() => {
@@ -49,500 +52,69 @@ afterEach(() => {
rmSync(stateDir, { recursive: true, force: true }); rmSync(stateDir, { recursive: true, force: true });
}); });
function writeSnooze(version: string, level: number, epochSeconds: number) { describe('gstack-update-check compatibility boundary', () => {
writeFileSync(join(stateDir, 'update-snoozed'), `${version} ${level} ${epochSeconds}`); test('passive invocation is a no-op even when an update and legacy state exist', () => {
} writeFileSync(join(gstackDir, 'VERSION'), '1.0.0\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '2.0.0\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 1.0.0 2.0.0');
writeFileSync(join(stateDir, 'update-snoozed'), '2.0.0 3 1');
function writeConfig(content: string) { expect(run()).toEqual({ exitCode: 0, stdout: '', stderr: '' });
writeFileSync(join(stateDir, 'config.yaml'), content); expect(readFileSync(join(stateDir, 'last-update-check'), 'utf8')).toContain('UPGRADE_AVAILABLE');
} expect(existsSync(join(stateDir, 'update-snoozed'))).toBe(true);
function nowEpoch(): number {
return Math.floor(Date.now() / 1000);
}
describe('gstack-update-check', () => {
// ─── Path A: No VERSION file ────────────────────────────────
test('exits 0 with no output when VERSION file is missing', () => {
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('');
}); });
// ─── Path B: Empty VERSION file ───────────────────────────── test('passive invocation performs no network or state setup', () => {
test('exits 0 with no output when VERSION file is empty', () => { writeFileSync(join(gstackDir, 'VERSION'), '1.0.0\n');
writeFileSync(join(gstackDir, 'VERSION'), ''); const missingStateDir = join(stateDir, 'not-created');
const { exitCode, stdout } = run(); const result = run([], {
expect(exitCode).toBe(0); GSTACK_STATE_DIR: missingStateDir,
expect(stdout).toBe(''); GSTACK_REMOTE_URL: 'https://127.0.0.1:1/must-not-be-requested',
});
// ─── Path C: Just-upgraded marker ───────────────────────────
test('outputs JUST_UPGRADED and deletes marker', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.4.0\n');
writeFileSync(join(stateDir, 'just-upgraded-from'), '0.3.3\n');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('JUST_UPGRADED 0.3.3 0.4.0');
// Marker should be deleted
expect(existsSync(join(stateDir, 'just-upgraded-from'))).toBe(false);
// Cache should be written
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8');
expect(cache).toContain('UP_TO_DATE');
});
// ─── Path C2: Just-upgraded marker + newer remote ──────────
test('just-upgraded marker does not mask newer remote version', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.4.0\n');
writeFileSync(join(stateDir, 'just-upgraded-from'), '0.3.3\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.5.0\n');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
// Should output both the just-upgraded notice AND the new upgrade
expect(stdout).toContain('JUST_UPGRADED 0.3.3 0.4.0');
expect(stdout).toContain('UPGRADE_AVAILABLE 0.4.0 0.5.0');
// Cache should reflect the upgrade available, not UP_TO_DATE
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8');
expect(cache).toContain('UPGRADE_AVAILABLE 0.4.0 0.5.0');
});
// ─── Path C3: Just-upgraded marker + remote matches local ──
test('just-upgraded with no further updates writes UP_TO_DATE cache', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.4.0\n');
writeFileSync(join(stateDir, 'just-upgraded-from'), '0.3.3\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.4.0\n');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('JUST_UPGRADED 0.3.3 0.4.0');
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8');
expect(cache).toContain('UP_TO_DATE');
});
// ─── Path D1: Fresh cache, UP_TO_DATE ───────────────────────
test('exits silently when cache says UP_TO_DATE and is fresh', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UP_TO_DATE 0.3.3');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('');
});
// ─── Path D1b: Fresh UP_TO_DATE cache, but local version changed ──
test('re-checks when UP_TO_DATE cache version does not match local', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.4.0\n');
// Cache says UP_TO_DATE for 0.3.3, but local is now 0.4.0
writeFileSync(join(stateDir, 'last-update-check'), 'UP_TO_DATE 0.3.3');
// Remote says 0.5.0 — should detect upgrade
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.5.0\n');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('UPGRADE_AVAILABLE 0.4.0 0.5.0');
});
// ─── Path D2: Fresh cache, UPGRADE_AVAILABLE ────────────────
test('echoes cached UPGRADE_AVAILABLE when cache is fresh', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 0.3.3 0.4.0');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0');
});
// ─── Path D3: Fresh cache, but local version changed ────────
test('re-checks when local version does not match cached old version', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.4.0\n');
// Cache says 0.3.3 → 0.4.0 but we're already on 0.4.0
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 0.3.3 0.4.0');
// Remote also says 0.4.0 — should be up to date
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.4.0\n');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe(''); // Up to date after re-check
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8');
expect(cache).toContain('UP_TO_DATE');
});
// ─── Path E: Versions match (remote fetch) ─────────────────
test('writes UP_TO_DATE cache when versions match', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.3.3\n');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('');
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8');
expect(cache).toContain('UP_TO_DATE');
});
// ─── Path F: Versions differ (remote fetch) ─────────────────
test('outputs UPGRADE_AVAILABLE when versions differ', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.4.0\n');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0');
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8');
expect(cache).toContain('UPGRADE_AVAILABLE 0.3.3 0.4.0');
});
// ─── Path G: Invalid remote response ────────────────────────
test('treats invalid remote response as up to date', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '<html>404 Not Found</html>\n');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('');
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8');
expect(cache).toContain('UP_TO_DATE');
});
// ─── Path H: Curl fails (bad URL) ──────────────────────────
test('exits silently when remote URL is unreachable', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
const { exitCode, stdout } = run({
GSTACK_REMOTE_URL: 'file:///nonexistent/path/VERSION',
}); });
expect(exitCode).toBe(0); expect(result).toEqual({ exitCode: 0, stdout: '', stderr: '' });
expect(stdout).toBe(''); expect(existsSync(missingStateDir)).toBe(false);
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8');
expect(cache).toContain('UP_TO_DATE');
}); });
// ─── Path I: Corrupt cache file ───────────────────────────── test('--force reports and caches a newer valid version', () => {
test('falls through to remote fetch when cache is corrupt', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'garbage data here');
// Remote says same version — should end up UP_TO_DATE
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.3.3\n');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('');
// Cache should be overwritten with valid content
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8');
expect(cache).toContain('UP_TO_DATE');
});
// ─── State dir creation ─────────────────────────────────────
test('creates state dir if it does not exist', () => {
const newStateDir = join(stateDir, 'nested', 'dir');
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.3.3\n');
const { exitCode } = run({ GSTACK_STATE_DIR: newStateDir });
expect(exitCode).toBe(0);
expect(existsSync(join(newStateDir, 'last-update-check'))).toBe(true);
});
// ─── E2E regression: always exit 0 ───────────────────────────
// Agents call this on every skill invocation. Exit code 1 breaks
// the preamble and confuses the agent. This test guards against
// regressions like the "exits 1 when up to date" bug.
test('exits 0 with real project VERSION and unreachable remote', () => {
// Simulate agent context: real VERSION file, network unavailable
const projectRoot = join(import.meta.dir, '..', '..');
const versionFile = join(projectRoot, 'VERSION');
if (!existsSync(versionFile)) return; // skip if no VERSION
const version = readFileSync(versionFile, 'utf-8').trim();
// Copy VERSION into test dir
writeFileSync(join(gstackDir, 'VERSION'), version + '\n');
// Remote is unreachable (simulates offline / CI / sandboxed agent)
const { exitCode, stdout } = run({
GSTACK_REMOTE_URL: 'file:///nonexistent/path/VERSION',
});
expect(exitCode).toBe(0);
// Should write UP_TO_DATE cache (not crash)
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8');
expect(cache).toContain('UP_TO_DATE');
});
test('exits 0 when up to date (not exit 1)', () => {
// Regression test: script previously exited 1 when versions matched.
// This broke every skill preamble that called it without || true.
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.3.3\n');
// First call: fetches remote, writes cache
const first = run();
expect(first.exitCode).toBe(0);
expect(first.stdout).toBe('');
// Second call: reads fresh cache
const second = run();
expect(second.exitCode).toBe(0);
expect(second.stdout).toBe('');
// Third call with upgrade available: still exit 0
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.4.0\n');
rmSync(join(stateDir, 'last-update-check')); // force re-fetch
const third = run();
expect(third.exitCode).toBe(0);
expect(third.stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0');
});
// ─── Snooze tests ───────────────────────────────────────────
test('snoozed level 1 within 24h → silent (cached path)', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 0.3.3 0.4.0');
writeSnooze('0.4.0', 1, nowEpoch() - 3600); // 1h ago (within 24h)
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('');
});
test('snoozed level 1 expired (25h ago) → outputs UPGRADE_AVAILABLE', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 0.3.3 0.4.0');
writeSnooze('0.4.0', 1, nowEpoch() - 90000); // 25h ago
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0');
});
test('snoozed level 2 within 48h → silent', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 0.3.3 0.4.0');
writeSnooze('0.4.0', 2, nowEpoch() - 86400); // 24h ago (within 48h)
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('');
});
test('snoozed level 2 expired (49h ago) → outputs', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 0.3.3 0.4.0');
writeSnooze('0.4.0', 2, nowEpoch() - 176400); // 49h ago
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0');
});
test('snoozed level 3 within 7d → silent', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 0.3.3 0.4.0');
writeSnooze('0.4.0', 3, nowEpoch() - 518400); // 6d ago (within 7d)
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('');
});
test('snoozed level 3 expired (8d ago) → outputs', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 0.3.3 0.4.0');
writeSnooze('0.4.0', 3, nowEpoch() - 691200); // 8d ago
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0');
});
test('snooze ignored when version differs (new version resets snooze)', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 0.3.3 0.5.0');
// Snoozed for 0.4.0, but remote is now 0.5.0
writeSnooze('0.4.0', 3, nowEpoch() - 60); // very recent
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.5.0');
});
test('corrupt snooze file → outputs normally', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 0.3.3 0.4.0');
writeFileSync(join(stateDir, 'update-snoozed'), 'garbage');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0');
});
test('non-numeric epoch in snooze file → outputs', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 0.3.3 0.4.0');
writeFileSync(join(stateDir, 'update-snoozed'), '0.4.0 1 abc');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0');
});
test('non-numeric level in snooze file → outputs', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 0.3.3 0.4.0');
writeFileSync(join(stateDir, 'update-snoozed'), `0.4.0 abc ${nowEpoch()}`);
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0');
});
test('snooze respected on remote fetch path (no cache)', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.4.0\n');
// No cache file — goes to remote fetch path
writeSnooze('0.4.0', 1, nowEpoch() - 3600); // 1h ago
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('');
// Cache should still be written
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8');
expect(cache).toContain('UPGRADE_AVAILABLE 0.3.3 0.4.0');
});
test('just-upgraded clears snooze file', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.4.0\n');
writeFileSync(join(stateDir, 'just-upgraded-from'), '0.3.3\n');
writeSnooze('0.4.0', 2, nowEpoch() - 3600);
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('JUST_UPGRADED 0.3.3 0.4.0');
expect(existsSync(join(stateDir, 'update-snoozed'))).toBe(false);
});
// ─── Config tests ──────────────────────────────────────────
test('update_check: false disables all checks', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.4.0\n');
writeConfig('update_check: false\n');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('');
// No cache should be written
expect(existsSync(join(stateDir, 'last-update-check'))).toBe(false);
});
test('missing config.yaml does not crash', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.4.0\n');
// No config file — should behave normally
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0');
});
// ─── --force flag tests ──────────────────────────────────────
test('--force busts fresh UP_TO_DATE cache', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.4.0\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UP_TO_DATE 0.3.3');
// Without --force: cache hit, silent
const cached = run();
expect(cached.stdout).toBe('');
// With --force: cache busted, re-fetches, finds upgrade
const forced = run({}, ['--force']);
expect(forced.exitCode).toBe(0);
expect(forced.stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0');
});
test('--force busts fresh UPGRADE_AVAILABLE cache', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.3.3\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UPGRADE_AVAILABLE 0.3.3 0.4.0');
// Without --force: cache hit, outputs stale upgrade
const cached = run();
expect(cached.stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0');
// With --force: cache busted, re-fetches, now up to date
const forced = run({}, ['--force']);
expect(forced.exitCode).toBe(0);
expect(forced.stdout).toBe('');
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8');
expect(cache).toContain('UP_TO_DATE');
});
test('--force clears snooze so user can upgrade after snoozing', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.4.0\n');
writeSnooze('0.4.0', 1, nowEpoch() - 60); // snoozed 1 min ago (within 24h)
// Without --force: snoozed, silent
const snoozed = run();
expect(snoozed.exitCode).toBe(0);
expect(snoozed.stdout).toBe('');
// With --force: snooze cleared, outputs upgrade
const forced = run({}, ['--force']);
expect(forced.exitCode).toBe(0);
expect(forced.stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0');
// Snooze file should be deleted
expect(existsSync(join(stateDir, 'update-snoozed'))).toBe(false);
});
// ─── Split TTL tests ─────────────────────────────────────────
// ─── Semver-order guard ─────────────────────────────────────
// When the upstream raw CDN serves a stale (older) VERSION right after a
// release, the script previously emitted a backwards UPGRADE_AVAILABLE
// line. The guard treats REMOTE < LOCAL as up-to-date.
test('remote older than local (stale CDN) → silent, cache UP_TO_DATE', () => {
writeFileSync(join(gstackDir, 'VERSION'), '1.34.0.0\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '1.33.2.0\n');
const { exitCode, stdout } = run();
expect(exitCode).toBe(0);
expect(stdout).toBe('');
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8');
expect(cache).toContain('UP_TO_DATE 1.34.0.0');
});
test('multi-segment sort: 1.9.0.0 < 1.10.0.0', () => {
writeFileSync(join(gstackDir, 'VERSION'), '1.9.0.0\n'); writeFileSync(join(gstackDir, 'VERSION'), '1.9.0.0\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '1.10.0.0\n'); writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '1.10.0.0\n');
const { stdout } = run(); expect(run(['--force']).stdout).toBe('UPGRADE_AVAILABLE 1.9.0.0 1.10.0.0');
expect(stdout).toBe('UPGRADE_AVAILABLE 1.9.0.0 1.10.0.0'); expect(readFileSync(join(stateDir, 'last-update-check'), 'utf8').trim())
.toBe('UPGRADE_AVAILABLE 1.9.0.0 1.10.0.0');
}); });
test('multi-segment reverse sort: 1.10.0.0 > 1.9.0.0 → no rewind', () => { test('--force never offers a downgrade', () => {
writeFileSync(join(gstackDir, 'VERSION'), '1.10.0.0\n'); writeFileSync(join(gstackDir, 'VERSION'), '1.10.0.0\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '1.9.0.0\n'); writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '1.9.0.0\n');
const { stdout } = run(); expect(run(['--force']).stdout).toBe('');
expect(stdout).toBe(''); expect(readFileSync(join(stateDir, 'last-update-check'), 'utf8').trim())
const cache = readFileSync(join(stateDir, 'last-update-check'), 'utf-8'); .toBe('UP_TO_DATE 1.10.0.0');
expect(cache).toContain('UP_TO_DATE 1.10.0.0');
}); });
test('UP_TO_DATE cache expires after 60 min (not 720)', () => { test('--force treats malformed or unavailable responses as non-updates', () => {
writeFileSync(join(gstackDir, 'VERSION'), '0.3.3\n'); writeFileSync(join(gstackDir, 'VERSION'), '1.0.0\n');
writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '0.4.0\n'); writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '<html>not a version</html>\n');
writeFileSync(join(stateDir, 'last-update-check'), 'UP_TO_DATE 0.3.3');
// Set cache mtime to 90 minutes ago (past 60-min TTL) expect(run(['--force']).stdout).toBe('');
const ninetyMinAgo = new Date(Date.now() - 90 * 60 * 1000); expect(readFileSync(join(stateDir, 'last-update-check'), 'utf8').trim())
const cachePath = join(stateDir, 'last-update-check'); .toBe('UP_TO_DATE 1.0.0');
utimesSync(cachePath, ninetyMinAgo, ninetyMinAgo); });
// Cache should be stale at 60-min TTL, re-fetches and finds upgrade test('--force clears obsolete snooze state and consumes the upgrade marker', () => {
const { exitCode, stdout } = run(); writeFileSync(join(gstackDir, 'VERSION'), '1.0.0\n');
expect(exitCode).toBe(0); writeFileSync(join(gstackDir, 'REMOTE_VERSION'), '1.0.0\n');
expect(stdout).toBe('UPGRADE_AVAILABLE 0.3.3 0.4.0'); writeFileSync(join(stateDir, 'just-upgraded-from'), '0.9.0\n');
writeFileSync(join(stateDir, 'update-snoozed'), '1.0.0 3 9999999999');
expect(run(['--force']).stdout).toBe('JUST_UPGRADED 0.9.0 1.0.0');
expect(existsSync(join(stateDir, 'just-upgraded-from'))).toBe(false);
expect(existsSync(join(stateDir, 'update-snoozed'))).toBe(false);
});
test('--force with no local version exits cleanly without creating a cache', () => {
expect(run(['--force'])).toEqual({ exitCode: 0, stdout: '', stderr: '' });
expect(existsSync(join(stateDir, 'last-update-check'))).toBe(false);
}); });
}); });
+3 -2
View File
@@ -4,7 +4,7 @@ import { validateReadPath, SENSITIVE_COOKIE_NAME, SENSITIVE_COOKIE_VALUE } from
import { BLOCKED_METADATA_HOSTS } from '../src/url-validation'; import { BLOCKED_METADATA_HOSTS } from '../src/url-validation';
import { readFileSync, symlinkSync, unlinkSync, writeFileSync, realpathSync } from 'fs'; import { readFileSync, symlinkSync, unlinkSync, writeFileSync, realpathSync } from 'fs';
import { tmpdir } from 'os'; import { tmpdir } from 'os';
import { join } from 'path'; import { join, relative } from 'path';
describe('validateOutputPath', () => { describe('validateOutputPath', () => {
it('allows paths within /tmp', () => { it('allows paths within /tmp', () => {
@@ -82,7 +82,8 @@ describe('validateReadPath', () => {
}); });
it('blocks nested path traversal', () => { it('blocks nested path traversal', () => {
expect(() => validateReadPath('src/../../etc/passwd')).toThrow(/Path must be within/); const escapeToEtc = relative(process.cwd(), '/etc/passwd');
expect(() => validateReadPath(`src/../${escapeToEtc}`)).toThrow(/Path must be within/);
}); });
it('blocks symlink inside safe dir pointing outside', () => { it('blocks symlink inside safe dir pointing outside', () => {
+68 -55
View File
@@ -5,55 +5,64 @@
"": { "": {
"name": "gstack", "name": "gstack",
"dependencies": { "dependencies": {
"@anthropic-ai/sdk": "^0.78.0", "@anthropic-ai/sdk": "^0.112.4",
"@ngrok/ngrok": "^1.7.0", "@ngrok/ngrok": "^1.7.0",
"diff": "^9.0.0", "diff": "^9.0.0",
"html-to-docx": "1.8.0", "html-to-docx": "1.8.0",
"marked": "^18.0.2", "marked": "^18.0.6",
"playwright": "npm:playwright-core@^1.58.2", "playwright": "npm:playwright-core@^1.58.2",
"sharp": "^0.34.5", "sharp": "^0.34.5",
"socks": "^2.8.8", "socks": "^2.8.9",
"xterm": "5", "xterm": "5",
"xterm-addon-fit": "^0.8.0", "xterm-addon-fit": "^0.8.0",
}, },
"devDependencies": { "devDependencies": {
"@anthropic-ai/claude-agent-sdk": "0.2.117", "@anthropic-ai/claude-agent-sdk": "0.3.216",
"@huggingface/transformers": "^4.1.0", "@huggingface/transformers": "4.2.0",
}, },
}, },
}, },
"overrides": {
"@protobufjs/utf8": "1.1.1",
"adm-zip": "0.6.0",
"fast-uri": "3.1.3",
"hono": "4.12.27",
"ip-address": "10.2.0",
"protobufjs": "7.6.5",
"qs": "6.15.2",
},
"packages": { "packages": {
"@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.2.117", "", { "dependencies": { "@anthropic-ai/sdk": "^0.81.0", "@modelcontextprotocol/sdk": "^1.29.0" }, "optionalDependencies": { "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.2.117", "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.2.117", "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.2.117", "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.2.117", "@anthropic-ai/claude-agent-sdk-linux-x64": "0.2.117", "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.2.117", "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.2.117", "@anthropic-ai/claude-agent-sdk-win32-x64": "0.2.117" }, "peerDependencies": { "zod": "^4.0.0" } }, "sha512-pVBss1Vu0w87nKCBhWtjMggSgCh6GVUtdRmuE58ZvXv0E2q0JcnUCQHehmn92BAW0+VCwPY8q/k7uKWkgwz/gA=="], "@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.3.216", "", { "optionalDependencies": { "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.216", "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.216", "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.216", "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.216", "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.216", "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.216", "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.216", "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.216" }, "peerDependencies": { "@anthropic-ai/sdk": ">=0.93.0", "@modelcontextprotocol/sdk": "^1.29.0", "zod": "^4.0.0" } }, "sha512-Fl/d9yGW7Pm0aGwUNkJMvruOVobleYcoprGJqufdP4J9W2XL/2xKXqanY8KqUdfySRMI2N46rY4/lryq5SfgFg=="],
"@anthropic-ai/claude-agent-sdk-darwin-arm64": ["@anthropic-ai/claude-agent-sdk-darwin-arm64@0.2.117", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ZeC/Lz8XMKQ5w+GmjTziPR8bSSarBtNCJMkMAYRT9ekNmyXSWXEwGLENe5TDDmtpzNNzAB1mQNuIYoqTsqgV3w=="], "@anthropic-ai/claude-agent-sdk-darwin-arm64": ["@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.216", "", { "os": "darwin", "cpu": "arm64" }, "sha512-TWtTUabXj+AMOBMknSe3EVQb/7qucw5pHYi0HWoKoixQt1JE6J/CiLDBIY69OD3eQn9k1XG6LaurT239kFxLUw=="],
"@anthropic-ai/claude-agent-sdk-darwin-x64": ["@anthropic-ai/claude-agent-sdk-darwin-x64@0.2.117", "", { "os": "darwin", "cpu": "x64" }, "sha512-DKyggGzzpDcr9S435xlpbpwkEYKZNbePSekug75tJclK8l4ddD9+M9BFgMiSUq9F1Zt53kUaRDihDu/cBKvkdQ=="], "@anthropic-ai/claude-agent-sdk-darwin-x64": ["@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.216", "", { "os": "darwin", "cpu": "x64" }, "sha512-tULuvqhJUwGTj71Uln4uPumm0la4EO1XydFbISTbdc1BsuvGx3FOtFcVs0Qg3dhNBFAoU/iYVTO/B1rImeJZig=="],
"@anthropic-ai/claude-agent-sdk-linux-arm64": ["@anthropic-ai/claude-agent-sdk-linux-arm64@0.2.117", "", { "os": "linux", "cpu": "arm64" }, "sha512-jyHmyZQavpPOe3zxBRX3KbdOAJ8JwZ8m/wMr5bhHhhcstugm/vJx6IIs7D44VvFjk+8sqdvR2ZrliL8PUcJL0g=="], "@anthropic-ai/claude-agent-sdk-linux-arm64": ["@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.216", "", { "os": "linux", "cpu": "arm64" }, "sha512-kX6x0otwOuA1zIeEiuAKQqOk2TUAOkDUzm4MmLoQHOM2xWvr/pc+xY4DZxaX4ef9dUFQuHA4r5Vtbk7tPTL7Bw=="],
"@anthropic-ai/claude-agent-sdk-linux-arm64-musl": ["@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.2.117", "", { "os": "linux", "cpu": "arm64" }, "sha512-bJU5gEOmM4VCOn4h8vipOKgdhPATePQ23mMpvyVqtVyipWppHfOUfVkqXb+SrF/hfkNSMYxDuoKxbJ+MmKtGjg=="], "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": ["@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.216", "", { "os": "linux", "cpu": "arm64" }, "sha512-sisWj2nhQolKu6aGWnu+I7d8EU6/m5J3G6bGfR7YvZ1wkQTQZAX3aOq6DVLIfCaZSH22wtqyuXhE/gn5eU1syw=="],
"@anthropic-ai/claude-agent-sdk-linux-x64": ["@anthropic-ai/claude-agent-sdk-linux-x64@0.2.117", "", { "os": "linux", "cpu": "x64" }, "sha512-Zb5PXKrDNbQ1dyNYwxZMNL+F2Dhgjh9f9B21wZUJqkhJL69hRJwJyxO42HiNmB2zGCaTxQTyjPhLdB/eQJo74Q=="], "@anthropic-ai/claude-agent-sdk-linux-x64": ["@anthropic-ai/claude-agent-sdk-linux-x64@0.3.216", "", { "os": "linux", "cpu": "x64" }, "sha512-WbJTLQafcYw9wl+gh/YpepdbWsOoJS7JZQA0obpzBBWzpx9PqPbjUDXDfCDrtzDI2fmr3Nz0//vC12bvlMZd8g=="],
"@anthropic-ai/claude-agent-sdk-linux-x64-musl": ["@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.2.117", "", { "os": "linux", "cpu": "x64" }, "sha512-LIkKTAYZGugEVssAuWCPqlDWSqhVZAveNPNsfKLbuG1naIMCR04fUqil6i3d3mAAfk7FaS5D4IdHp45psi+GDw=="], "@anthropic-ai/claude-agent-sdk-linux-x64-musl": ["@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.216", "", { "os": "linux", "cpu": "x64" }, "sha512-3Ts2Ab6oEGG2r+epmWc6lOR1ahECjvH4y+lPb32qLKMdYxT2PU6TAc4Z/USLLuqDpgw3nSb8xuiYEH77rv88fw=="],
"@anthropic-ai/claude-agent-sdk-win32-arm64": ["@anthropic-ai/claude-agent-sdk-win32-arm64@0.2.117", "", { "os": "win32", "cpu": "arm64" }, "sha512-uetggH3B83PiH0a9D/5MVXB5Hqnlr2DVajehwAP2x0Mt4DBd632ICnHpu6pnSP+vVkWgq3FgQlkHe91RfP+peA=="], "@anthropic-ai/claude-agent-sdk-win32-arm64": ["@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.216", "", { "os": "win32", "cpu": "arm64" }, "sha512-xGB8rKatsXl9enqmPXixYNvdjGh1AL2jFmMRC9lR9M1prf2FGl7dkpdHz8YyItKAciRwpPIfts/9dSGhxlgT3A=="],
"@anthropic-ai/claude-agent-sdk-win32-x64": ["@anthropic-ai/claude-agent-sdk-win32-x64@0.2.117", "", { "os": "win32", "cpu": "x64" }, "sha512-TT4KngAokDTJSvQ2mrAP6ZRkXj50OLj7Tb1zZA4CnkmrrEidgs4KrMx7er1ZwoivngIvCekV9+TbtC9giknr5w=="], "@anthropic-ai/claude-agent-sdk-win32-x64": ["@anthropic-ai/claude-agent-sdk-win32-x64@0.3.216", "", { "os": "win32", "cpu": "x64" }, "sha512-cGbBgoKNzB6wRL6bMOwM2iJEG/wx0B6FCblmKF+ZAYKcj5oNi3jM6oQsnPJbKfrzVKrip3YEpXxopQ9O30LrSg=="],
"@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.78.0", "", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-PzQhR715td/m1UaaN5hHXjYB8Gl2lF9UVhrrGrZeysiF6Rb74Wc9GCB8hzLdzmQtBd1qe89F9OptgB9Za1Ib5w=="], "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.112.4", "", { "dependencies": { "json-schema-to-ts": "^3.1.1", "standardwebhooks": "^1.0.0" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-7eXJJnrmBI5GMC6drrCiSkycVsT7crRZX3qv5HusLSm+qiILjmtqP7gf+UiT7ASu/7Gdj+Zfl4f2haV8wATKUg=="],
"@babel/runtime": ["@babel/runtime@7.29.2", "", {}, "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g=="], "@babel/runtime": ["@babel/runtime@7.29.7", "", {}, "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw=="],
"@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="], "@emnapi/runtime": ["@emnapi/runtime@1.11.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA=="],
"@hono/node-server": ["@hono/node-server@1.19.14", "", { "peerDependencies": { "hono": "^4" } }, "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw=="], "@hono/node-server": ["@hono/node-server@1.19.14", "", { "peerDependencies": { "hono": "^4" } }, "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw=="],
"@huggingface/jinja": ["@huggingface/jinja@0.5.7", "", {}, "sha512-OosMEbF/R6zkKNNzqhI7kvKYCpo1F0UeIv46/h4D4UjVEKKd6k3TiV8sgu6fkreX4lbBiRI+lZG8UnXnqVQmEQ=="], "@huggingface/jinja": ["@huggingface/jinja@0.5.9", "", {}, "sha512-uWTG+l3VJRsl7EXxYizuL3P+cCPoc3cRqbWWRcQN0FhejRfbdq0RNhCmbY/YDtnTcz9icdLYuLDjsnz4d8JMuw=="],
"@huggingface/tokenizers": ["@huggingface/tokenizers@0.1.3", "", {}, "sha512-8rF/RRT10u+kn7YuUbUg0OF30K8rjTc78aHpxT+qJ1uWSqxT1MHi8+9ltwYfkFYJzT/oS+qw3JVfHtNMGAdqyA=="], "@huggingface/tokenizers": ["@huggingface/tokenizers@0.1.3", "", {}, "sha512-8rF/RRT10u+kn7YuUbUg0OF30K8rjTc78aHpxT+qJ1uWSqxT1MHi8+9ltwYfkFYJzT/oS+qw3JVfHtNMGAdqyA=="],
"@huggingface/transformers": ["@huggingface/transformers@4.1.0", "", { "dependencies": { "@huggingface/jinja": "^0.5.6", "@huggingface/tokenizers": "^0.1.3", "onnxruntime-node": "1.24.3", "onnxruntime-web": "1.26.0-dev.20260410-5e55544225", "sharp": "^0.34.5" } }, "sha512-WiMf9eyvF6V2pj4gs12A7GQV3svyFIBtB/W+Hn5lT5E5DyqWUno1ZrWoAfJv69X1RNv/0GoOo6DFmL6NOYd+rg=="], "@huggingface/transformers": ["@huggingface/transformers@4.2.0", "", { "dependencies": { "@huggingface/jinja": "^0.5.6", "@huggingface/tokenizers": "^0.1.3", "onnxruntime-node": "1.24.3", "onnxruntime-web": "1.26.0-dev.20260416-b7804b056c", "sharp": "^0.34.5" } }, "sha512-8BRCoBMH0XsWaEIamuR0LrJGAfftgHAfb2Vrffy0VKlSAE/MnUJ5/h/zTfEP3fDIft+nk7TqB8xXEyABGitBjQ=="],
"@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="], "@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="],
@@ -147,33 +156,33 @@
"@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="], "@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="],
"@protobufjs/codegen": ["@protobufjs/codegen@2.0.4", "", {}, "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="], "@protobufjs/codegen": ["@protobufjs/codegen@2.0.5", "", {}, "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g=="],
"@protobufjs/eventemitter": ["@protobufjs/eventemitter@1.1.0", "", {}, "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="], "@protobufjs/eventemitter": ["@protobufjs/eventemitter@1.1.1", "", {}, "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg=="],
"@protobufjs/fetch": ["@protobufjs/fetch@1.1.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" } }, "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ=="], "@protobufjs/fetch": ["@protobufjs/fetch@1.1.1", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.1" } }, "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw=="],
"@protobufjs/float": ["@protobufjs/float@1.0.2", "", {}, "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="], "@protobufjs/float": ["@protobufjs/float@1.0.2", "", {}, "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="],
"@protobufjs/inquire": ["@protobufjs/inquire@1.1.0", "", {}, "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="],
"@protobufjs/path": ["@protobufjs/path@1.1.2", "", {}, "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="], "@protobufjs/path": ["@protobufjs/path@1.1.2", "", {}, "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="],
"@protobufjs/pool": ["@protobufjs/pool@1.1.0", "", {}, "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="], "@protobufjs/pool": ["@protobufjs/pool@1.1.0", "", {}, "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="],
"@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="], "@protobufjs/utf8": ["@protobufjs/utf8@1.1.1", "", {}, "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg=="],
"@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="], "@stablelib/base64": ["@stablelib/base64@1.0.1", "", {}, "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ=="],
"@types/node": ["@types/node@26.1.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw=="],
"accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
"adm-zip": ["adm-zip@0.5.17", "", {}, "sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ=="], "adm-zip": ["adm-zip@0.6.0", "", {}, "sha512-XleryMhbuksdKtofnWZ9Sk+4CUTbms4Mb/EU32SZwToAyZ5RgVos/ki8n+yr0LWHOGKuakbXTuuYNHLQjhddgg=="],
"ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], "ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="],
"ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="],
"body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="], "body-parser": ["body-parser@2.3.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^2.0.0", "debug": "^4.4.3", "http-errors": "^2.0.1", "iconv-lite": "^0.7.2", "on-finished": "^2.4.1", "qs": "^6.15.2", "raw-body": "^3.0.2", "type-is": "^2.1.0" } }, "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw=="],
"boolean": ["boolean@3.2.0", "", {}, "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw=="], "boolean": ["boolean@3.2.0", "", {}, "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw=="],
@@ -203,7 +212,7 @@
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
"define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="],
@@ -243,7 +252,7 @@
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], "es-object-atoms": ["es-object-atoms@1.1.2", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw=="],
"es6-error": ["es6-error@4.1.1", "", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="], "es6-error": ["es6-error@4.1.1", "", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="],
@@ -257,15 +266,17 @@
"eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="], "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="],
"eventsource-parser": ["eventsource-parser@3.0.8", "", {}, "sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ=="], "eventsource-parser": ["eventsource-parser@3.1.0", "", {}, "sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg=="],
"express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="],
"express-rate-limit": ["express-rate-limit@8.3.2", "", { "dependencies": { "ip-address": "10.1.0" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-77VmFeJkO0/rvimEDuUC5H30oqUC4EyOhyGccfqoLebB0oiEYfM7nwPrsDsBL1gsTpwfzX8SFy2MT3TDyRq+bg=="], "express-rate-limit": ["express-rate-limit@8.6.0", "", { "dependencies": { "debug": "^4.4.3", "ip-address": "^10.2.0" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-XKJXDsASUOo0LLtFwW5hCcQGH0N4WQc/Rn8/Pvoia+TJFOkkFPvrtW9lZOeeNcxQJspvOIERMwiRLsVFlhHEkA=="],
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
"fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], "fast-sha256": ["fast-sha256@1.3.0", "", {}, "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ=="],
"fast-uri": ["fast-uri@3.1.3", "", {}, "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg=="],
"finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="],
@@ -297,9 +308,9 @@
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
"hasown": ["hasown@2.0.3", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg=="], "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="],
"hono": ["hono@4.12.14", "", {}, "sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w=="], "hono": ["hono@4.12.27", "", {}, "sha512-1yrb/+w6HWQJrUCLkJ2IF5jNIPvvFkblV5RNOYl6bV+OA6p9GLcMpHFFGTosSvHvcAUibuUukRqhlYI4z32C7Q=="],
"html-entities": ["html-entities@2.6.0", "", {}, "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ=="], "html-entities": ["html-entities@2.6.0", "", {}, "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ=="],
@@ -311,7 +322,7 @@
"http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="],
"iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], "iconv-lite": ["iconv-lite@0.7.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ=="],
"image-size": ["image-size@1.2.1", "", { "dependencies": { "queue": "6.0.2" }, "bin": { "image-size": "bin/image-size.js" } }, "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw=="], "image-size": ["image-size@1.2.1", "", { "dependencies": { "queue": "6.0.2" }, "bin": { "image-size": "bin/image-size.js" } }, "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw=="],
@@ -337,7 +348,7 @@
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
"jose": ["jose@6.2.2", "", {}, "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ=="], "jose": ["jose@6.2.3", "", {}, "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw=="],
"json-schema-to-ts": ["json-schema-to-ts@3.1.1", "", { "dependencies": { "@babel/runtime": "^7.18.3", "ts-algebra": "^2.0.0" } }, "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g=="], "json-schema-to-ts": ["json-schema-to-ts@3.1.1", "", { "dependencies": { "@babel/runtime": "^7.18.3", "ts-algebra": "^2.0.0" } }, "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g=="],
@@ -355,7 +366,7 @@
"long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="], "long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
"marked": ["marked@18.0.2", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-NsmlUYBS/Zg57rgDWMYdnre6OTj4e+qq/JS2ot3KrYLSoHLw+sDu0Nm1ZGpRgYAq6c+b1ekaY5NzVchMCQnzcg=="], "marked": ["marked@18.0.7", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-iDVQ5ldaiKXn6b2JroX5kgRfmwgqolW7NpaEzTl1k/2Zh1njIEN9yniyLV/mOvWwtsE8OGgkjsCYvijuPk1dtA=="],
"matcher": ["matcher@3.0.0", "", { "dependencies": { "escape-string-regexp": "^4.0.0" } }, "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng=="], "matcher": ["matcher@3.0.0", "", { "dependencies": { "escape-string-regexp": "^4.0.0" } }, "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng=="],
@@ -373,7 +384,7 @@
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="], "nanoid": ["nanoid@3.3.16", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="],
"negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
@@ -395,7 +406,7 @@
"onnxruntime-node": ["onnxruntime-node@1.24.3", "", { "dependencies": { "adm-zip": "^0.5.16", "global-agent": "^3.0.0", "onnxruntime-common": "1.24.3" }, "os": [ "linux", "win32", "darwin", ] }, "sha512-JH7+czbc8ALA819vlTgcV+Q214/+VjGeBHDjX81+ZCD0PCVCIFGFNtT0V4sXG/1JXypKPgScQcB3ij/hk3YnTg=="], "onnxruntime-node": ["onnxruntime-node@1.24.3", "", { "dependencies": { "adm-zip": "^0.5.16", "global-agent": "^3.0.0", "onnxruntime-common": "1.24.3" }, "os": [ "linux", "win32", "darwin", ] }, "sha512-JH7+czbc8ALA819vlTgcV+Q214/+VjGeBHDjX81+ZCD0PCVCIFGFNtT0V4sXG/1JXypKPgScQcB3ij/hk3YnTg=="],
"onnxruntime-web": ["onnxruntime-web@1.26.0-dev.20260410-5e55544225", "", { "dependencies": { "flatbuffers": "^25.1.24", "guid-typescript": "^1.0.9", "long": "^5.2.3", "onnxruntime-common": "1.24.0-dev.20251116-b39e144322", "platform": "^1.3.6", "protobufjs": "^7.2.4" } }, "sha512-hHd9n8DzIfGSAjM4Dvslesc8i6h9HEEcl8qt7X3LfhUxMgls6FBJ32j2xrDtJjKJFEehFeJmyB/pvad1I8KS8w=="], "onnxruntime-web": ["onnxruntime-web@1.26.0-dev.20260416-b7804b056c", "", { "dependencies": { "flatbuffers": "^25.1.24", "guid-typescript": "^1.0.9", "long": "^5.2.3", "onnxruntime-common": "1.24.0-dev.20251116-b39e144322", "platform": "^1.3.6", "protobufjs": "^7.2.4" } }, "sha512-MD6Ss4GSpQBo6zqoJzyT9LRbKYs7x/JVN23FT24EcEvlqF4VuzPOeH6X38orZPKHQDbprn7K+SBpu0/mj2CQiw=="],
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], "pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
@@ -409,23 +420,23 @@
"platform": ["platform@1.3.6", "", {}, "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg=="], "platform": ["platform@1.3.6", "", {}, "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg=="],
"playwright": ["playwright-core@1.58.2", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg=="], "playwright": ["playwright-core@1.61.1", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg=="],
"process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="], "process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],
"process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="], "process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
"protobufjs": ["protobufjs@7.5.5", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg=="], "protobufjs": ["protobufjs@7.6.5", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.5", "@protobufjs/eventemitter": "^1.1.1", "@protobufjs/fetch": "^1.1.1", "@protobufjs/float": "^1.0.2", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.1", "@types/node": ">=13.7.0", "long": "^5.3.2" } }, "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw=="],
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
"punycode": ["punycode@1.4.1", "", {}, "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="], "punycode": ["punycode@1.4.1", "", {}, "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="],
"qs": ["qs@6.15.1", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg=="], "qs": ["qs@6.15.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw=="],
"queue": ["queue@6.0.2", "", { "dependencies": { "inherits": "~2.0.3" } }, "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA=="], "queue": ["queue@6.0.2", "", { "dependencies": { "inherits": "~2.0.3" } }, "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA=="],
"range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], "range-parser": ["range-parser@1.3.0", "", {}, "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw=="],
"raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], "raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="],
@@ -443,7 +454,7 @@
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
"semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
"semver-compare": ["semver-compare@1.0.0", "", {}, "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow=="], "semver-compare": ["semver-compare@1.0.0", "", {}, "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow=="],
@@ -463,7 +474,7 @@
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], "side-channel": ["side-channel@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4", "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ=="],
"side-channel-list": ["side-channel-list@1.0.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" } }, "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w=="], "side-channel-list": ["side-channel-list@1.0.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" } }, "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w=="],
@@ -473,10 +484,12 @@
"smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], "smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="],
"socks": ["socks@2.8.8", "", { "dependencies": { "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" } }, "sha512-NlGELfPrgX2f1TAAcz0WawlLn+0r3FyhhCRpFFK2CemXenPYvzMWWZINv3eDNo9ucdwme7oCHRY0Jnbs4aIkog=="], "socks": ["socks@2.8.9", "", { "dependencies": { "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" } }, "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw=="],
"sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], "sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="],
"standardwebhooks": ["standardwebhooks@1.0.0", "", { "dependencies": { "@stablelib/base64": "^1.0.0", "fast-sha256": "^1.3.0" } }, "sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg=="],
"statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
"string-template": ["string-template@0.2.1", "", {}, "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw=="], "string-template": ["string-template@0.2.1", "", {}, "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw=="],
@@ -493,9 +506,9 @@
"type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="], "type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="],
"type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], "type-is": ["type-is@2.1.0", "", { "dependencies": { "content-type": "^2.0.0", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA=="],
"undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
"unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
@@ -525,12 +538,10 @@
"xterm-addon-fit": ["xterm-addon-fit@0.8.0", "", { "peerDependencies": { "xterm": "^5.0.0" } }, "sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw=="], "xterm-addon-fit": ["xterm-addon-fit@0.8.0", "", { "peerDependencies": { "xterm": "^5.0.0" } }, "sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw=="],
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="],
"zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="], "zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="],
"@anthropic-ai/claude-agent-sdk/@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.81.0", "", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-D4K5PvEV6wPiRtVlVsJHIUhHAmOZ6IT/I9rKlTf84gR7GyyAurPJK7z9BOf/AZqC5d1DhYQGJNKRmV+q8dGhgw=="],
"@oozcitak/infra/@oozcitak/util": ["@oozcitak/util@8.0.0", "", {}, "sha512-+9Hq6yuoq/3TRV/n/xcpydGBq2qN2/DEDMqNTG7rm95K6ZE2/YY/sPyx62+1n8QsE9O26e5M1URlXsk+AnN9Jw=="], "@oozcitak/infra/@oozcitak/util": ["@oozcitak/util@8.0.0", "", {}, "sha512-+9Hq6yuoq/3TRV/n/xcpydGBq2qN2/DEDMqNTG7rm95K6ZE2/YY/sPyx62+1n8QsE9O26e5M1URlXsk+AnN9Jw=="],
"@oozcitak/url/@oozcitak/infra": ["@oozcitak/infra@1.0.3", "", { "dependencies": { "@oozcitak/util": "1.0.1" } }, "sha512-9O2wxXGnRzy76O1XUxESxDGsXT5kzETJPvYbreO4mv6bqe1+YSuux2cZTagjJ/T4UfEwFJz5ixanOqB0QgYAag=="], "@oozcitak/url/@oozcitak/infra": ["@oozcitak/infra@1.0.3", "", { "dependencies": { "@oozcitak/util": "1.0.1" } }, "sha512-9O2wxXGnRzy76O1XUxESxDGsXT5kzETJPvYbreO4mv6bqe1+YSuux2cZTagjJ/T4UfEwFJz5ixanOqB0QgYAag=="],
@@ -539,20 +550,22 @@
"accepts/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], "accepts/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="],
"body-parser/content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="],
"dom-serializer/domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], "dom-serializer/domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
"dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="], "dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="],
"express/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], "express/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="],
"express-rate-limit/ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="],
"htmlparser2/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], "htmlparser2/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
"onnxruntime-web/onnxruntime-common": ["onnxruntime-common@1.24.0-dev.20251116-b39e144322", "", {}, "sha512-BOoomdHYmNRL5r4iQ4bMvsl2t0/hzVQ3OM3PHD0gxeXu1PmggqBv3puZicEUVOA3AtHHYmqZtjMj9FOfGrATTw=="], "onnxruntime-web/onnxruntime-common": ["onnxruntime-common@1.24.0-dev.20251116-b39e144322", "", {}, "sha512-BOoomdHYmNRL5r4iQ4bMvsl2t0/hzVQ3OM3PHD0gxeXu1PmggqBv3puZicEUVOA3AtHHYmqZtjMj9FOfGrATTw=="],
"send/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], "send/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="],
"type-is/content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="],
"type-is/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], "type-is/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="],
"xmlbuilder2/@oozcitak/dom": ["@oozcitak/dom@1.15.5", "", { "dependencies": { "@oozcitak/infra": "1.0.5", "@oozcitak/url": "1.0.0", "@oozcitak/util": "8.0.0" } }, "sha512-L6v3Mwb0TaYBYgeYlIeBaHnc+2ZEaDSbFiRm5KmqZQSoBlbPlf+l6aIH/sD5GUf2MYwULw00LT7+dOnEuAEC0A=="], "xmlbuilder2/@oozcitak/dom": ["@oozcitak/dom@1.15.5", "", { "dependencies": { "@oozcitak/infra": "1.0.5", "@oozcitak/url": "1.0.0", "@oozcitak/util": "8.0.0" } }, "sha512-L6v3Mwb0TaYBYgeYlIeBaHnc+2ZEaDSbFiRm5KmqZQSoBlbPlf+l6aIH/sD5GUf2MYwULw00LT7+dOnEuAEC0A=="],
+75
View File
@@ -0,0 +1,75 @@
# Capability readiness
GStack's six public skills provide pure judgment without the optional runtime.
When a workflow needs executable evidence, inspect one of the five user-facing
capabilities without changing the machine:
```bash
gstack doctor --capability browser
gstack doctor --capability design --json
gstack doctor --capability diagram
gstack doctor --capability pdf
gstack doctor --capability ios
```
The focused result deliberately keeps five questions separate:
| Axis | Meaning |
|---|---|
| `judgment` | `available` even when no optional runtime exists. |
| `platform` | `supported` or `unsupported`; physical iOS is macOS-only. |
| `consent.preview` | Whether consent is required before an uncached public signed-manifest metadata request. Doctor never makes that request or grants consent. |
| `consent.install` | Separate consent required only after the complete preview. Doctor never installs or records consent. |
| `readiness` | Whether the selected local runtime capability is usable now. |
Readiness has exactly five states:
- `ready`: capability and managed-runtime checks passed.
- `degraded`: the capability passed, but the managed runtime reported a warning
such as recovery from an interrupted upgrade.
- `unavailable`: the capability is not selected, no runtime is active, or runtime
inspection could not establish availability.
- `unsupported`: the platform cannot provide the capability with GStack's
existing architecture.
- `failed`: an installed/selected capability failed its readiness evidence.
The JSON form follows the runtime's result convention: `ok` is true only for
`ready` and `degraded`; a non-ready focused doctor exits 1. Usage errors still
exit 2 through the standard CLI error envelope.
## Consent and setup flow
```text
pure judgment (always available)
|
v
capability doctor (local, non-mutating)
|
+-- ready/degraded --> capability-dependent work
|
+-- unsupported ----> judgment-only work or supported platform
|
+-- unavailable/failed
|
v
ask for preview consent
|
v
packaged bootstrap preview (no install)
|
v
ask for install consent
|
v
packaged bootstrap install
|
v
capability doctor again
```
Preview consent is not install consent. Deferring either does not block pure
judgment. Follow the packaged bootstrap contract for exact dependency closure,
compressed bytes, signature checks, and atomic installation. Do not run setup
from a standards-installed skill directory, add a browser provider, replace the
local Chromium/Playwright backend, or replace the physical-iOS
DebugBridge/CoreDevice harness.
+9 -9
View File
@@ -43,7 +43,7 @@
"prompt_sha256": "a0fcff9cad68f9305da861fa5a58990e1ef51d9d84298fe2df7ba8a2f56b1dba", "prompt_sha256": "a0fcff9cad68f9305da861fa5a58990e1ef51d9d84298fe2df7ba8a2f56b1dba",
"semantic_attempt_sha256": "7724c3d954f421753c597364c383bd76bc01ba9803f99fb14488287bb925aeb6" "semantic_attempt_sha256": "7724c3d954f421753c597364c383bd76bc01ba9803f99fb14488287bb925aeb6"
}, },
"policy_sha256": "951fd945e7ecb438bcedadccd563df430652d35f4cff1d513dfdcf16ee77d02d", "policy_sha256": "c7df25a16073d69da15243f258a2ef72a69c03ee3114eac2c19cf1c7e126532b",
"policy_present": true, "policy_present": true,
"prompt_is_not_authority_input": true, "prompt_is_not_authority_input": true,
"verdict": "PASS" "verdict": "PASS"
@@ -88,7 +88,7 @@
"prompt_sha256": "04d82a21358f188cb823dcceeecaebea0b4ed8b9c1f8d00220ef3b499c48b1c8", "prompt_sha256": "04d82a21358f188cb823dcceeecaebea0b4ed8b9c1f8d00220ef3b499c48b1c8",
"semantic_attempt_sha256": "9639406995955284517acb30f56b37dedc42a6c08142163dfa8fe0295105cbbf" "semantic_attempt_sha256": "9639406995955284517acb30f56b37dedc42a6c08142163dfa8fe0295105cbbf"
}, },
"policy_sha256": "e5fc3019062512de84ade87c8c45b34c8f46b95a65ef84a49fd25bbdee63e41e", "policy_sha256": "8dd78f6f8e01eb9cf1fe0f3f43d7fcd072a4f3f2f0dc14d9f1b5d3ff1250b972",
"policy_present": true, "policy_present": true,
"prompt_is_not_authority_input": true, "prompt_is_not_authority_input": true,
"verdict": "PASS" "verdict": "PASS"
@@ -138,7 +138,7 @@
"prompt_sha256": "8ad639f708a2ccd5c7c438b1dedf6afacdfa4eac3883a7a046ea23f29314e1c4", "prompt_sha256": "8ad639f708a2ccd5c7c438b1dedf6afacdfa4eac3883a7a046ea23f29314e1c4",
"semantic_attempt_sha256": "4c450039e4c622fbeaa34b7f7dfc810d3b7369aaf7e5f4d240cd6cc18a31331a" "semantic_attempt_sha256": "4c450039e4c622fbeaa34b7f7dfc810d3b7369aaf7e5f4d240cd6cc18a31331a"
}, },
"policy_sha256": "78df79ecb49744ff13f044b8f5a486705ef43172c4dc19d7dbc616d84f4d578c", "policy_sha256": "7c7ccb7ff64ea6c73b668848ae5a663606798abc345d7e5c6bb0880732bb29c3",
"policy_present": true, "policy_present": true,
"prompt_is_not_authority_input": true, "prompt_is_not_authority_input": true,
"verdict": "PASS" "verdict": "PASS"
@@ -188,7 +188,7 @@
"prompt_sha256": "d2aa9aee06a116bf04cb62772e8abdf8dbd606811b6d38565389c88e86c79ede", "prompt_sha256": "d2aa9aee06a116bf04cb62772e8abdf8dbd606811b6d38565389c88e86c79ede",
"semantic_attempt_sha256": "64885a66bdc6688b880cbb9a59babf314834c068eb040657501bf287bfcb0d2b" "semantic_attempt_sha256": "64885a66bdc6688b880cbb9a59babf314834c068eb040657501bf287bfcb0d2b"
}, },
"policy_sha256": "951fd945e7ecb438bcedadccd563df430652d35f4cff1d513dfdcf16ee77d02d", "policy_sha256": "c7df25a16073d69da15243f258a2ef72a69c03ee3114eac2c19cf1c7e126532b",
"policy_present": true, "policy_present": true,
"prompt_is_not_authority_input": true, "prompt_is_not_authority_input": true,
"verdict": "PASS" "verdict": "PASS"
@@ -232,7 +232,7 @@
"prompt_sha256": "377e3a2dfc7b04272f857d27e77c9aa3c9f36c3feb63c03e5aee3ecd3dea8e2a", "prompt_sha256": "377e3a2dfc7b04272f857d27e77c9aa3c9f36c3feb63c03e5aee3ecd3dea8e2a",
"semantic_attempt_sha256": "a49b1528091886749278dc22e7da4556c090800989b2bca9c0e1c09dd880fed7" "semantic_attempt_sha256": "a49b1528091886749278dc22e7da4556c090800989b2bca9c0e1c09dd880fed7"
}, },
"policy_sha256": "7a8cb7346851f9d948139dbf33cb8c6dd5eb8b2cc7de94e30a53824a94f027a6", "policy_sha256": "7969ac784f398b09cec2ad44f623de95f1e326721043272b12aaec1c622e840c",
"policy_present": true, "policy_present": true,
"prompt_is_not_authority_input": true, "prompt_is_not_authority_input": true,
"verdict": "PASS" "verdict": "PASS"
@@ -279,7 +279,7 @@
"prompt_sha256": "a01bb977de84e53d8ce3dfa427bcc93d73c6e449cd4e9c1ff63b436fd41fb0d1", "prompt_sha256": "a01bb977de84e53d8ce3dfa427bcc93d73c6e449cd4e9c1ff63b436fd41fb0d1",
"semantic_attempt_sha256": "ce5c64c62c3ff9b60949f34717dffbc908f62ce30f8a4a48ec182eba4363a206" "semantic_attempt_sha256": "ce5c64c62c3ff9b60949f34717dffbc908f62ce30f8a4a48ec182eba4363a206"
}, },
"policy_sha256": "a65efa55d992f63d0bdb356e1e8c4900b966364af1e22f0b6412e20e7ef30a58", "policy_sha256": "4134088a9b22fd7d3d2d6492c812ecbc55650df25ab1101189dd24721fe1763d",
"policy_present": true, "policy_present": true,
"prompt_is_not_authority_input": true, "prompt_is_not_authority_input": true,
"verdict": "PASS" "verdict": "PASS"
@@ -330,7 +330,7 @@
"prompt_sha256": "95e97e26268ad7e509527e0f54c943ed6c4105d919f250648a2ad59ce77cbdb9", "prompt_sha256": "95e97e26268ad7e509527e0f54c943ed6c4105d919f250648a2ad59ce77cbdb9",
"semantic_attempt_sha256": "dacd11a78e32aeb6c0065496bedd4a9770f7bbac1036e003d3768fac41eb84f0" "semantic_attempt_sha256": "dacd11a78e32aeb6c0065496bedd4a9770f7bbac1036e003d3768fac41eb84f0"
}, },
"policy_sha256": "951fd945e7ecb438bcedadccd563df430652d35f4cff1d513dfdcf16ee77d02d", "policy_sha256": "c7df25a16073d69da15243f258a2ef72a69c03ee3114eac2c19cf1c7e126532b",
"policy_present": true, "policy_present": true,
"prompt_is_not_authority_input": true, "prompt_is_not_authority_input": true,
"verdict": "PASS" "verdict": "PASS"
@@ -381,7 +381,7 @@
"prompt_sha256": "bdd7e8adfa7c15cf8531f84c3adaaacc725075f1a78f7487225300750547b82d", "prompt_sha256": "bdd7e8adfa7c15cf8531f84c3adaaacc725075f1a78f7487225300750547b82d",
"semantic_attempt_sha256": "32c11b63412c5d873ff29dcc87c45bef1b50daa218a5c6c1075864aa24d7c3b6" "semantic_attempt_sha256": "32c11b63412c5d873ff29dcc87c45bef1b50daa218a5c6c1075864aa24d7c3b6"
}, },
"policy_sha256": "951fd945e7ecb438bcedadccd563df430652d35f4cff1d513dfdcf16ee77d02d", "policy_sha256": "c7df25a16073d69da15243f258a2ef72a69c03ee3114eac2c19cf1c7e126532b",
"policy_present": true, "policy_present": true,
"prompt_is_not_authority_input": true, "prompt_is_not_authority_input": true,
"verdict": "PASS" "verdict": "PASS"
@@ -426,7 +426,7 @@
"prompt_sha256": "51b7d53bc342e8632e34ae31a167cbde568ab5ee2a6dd2ccc980583a30604164", "prompt_sha256": "51b7d53bc342e8632e34ae31a167cbde568ab5ee2a6dd2ccc980583a30604164",
"semantic_attempt_sha256": "06f77b27c9bd360562655b23ca00a0dd021bdb14ebaaf3d836845e4e0cb43d68" "semantic_attempt_sha256": "06f77b27c9bd360562655b23ca00a0dd021bdb14ebaaf3d836845e4e0cb43d68"
}, },
"policy_sha256": "65f28f454b67d4904c1857a2a6cfcff387c0aa6e4ae58aec490bc95289dce59f", "policy_sha256": "43d5cbbf88ed4f9afa3e7af214b4aa8c3a764a7006d76a864344df05d1f76392",
"policy_present": true, "policy_present": true,
"prompt_is_not_authority_input": true, "prompt_is_not_authority_input": true,
"verdict": "PASS" "verdict": "PASS"
+22 -103
View File
@@ -5,14 +5,19 @@
"": { "": {
"name": "@gstack/diagram-render", "name": "@gstack/diagram-render",
"dependencies": { "dependencies": {
"@excalidraw/excalidraw": "0.18.0", "@excalidraw/excalidraw": "0.18.1",
"@excalidraw/mermaid-to-excalidraw": "1.1.2", "@excalidraw/mermaid-to-excalidraw": "2.2.2",
"mermaid": "11.12.2", "mermaid": "11.16.0",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
}, },
}, },
}, },
"overrides": {
"dompurify": "3.4.11",
"lodash-es": "4.18.1",
"nanoid": "5.0.9",
},
"packages": { "packages": {
"@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="], "@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="],
@@ -26,17 +31,17 @@
"@chevrotain/regexp-to-ast": ["@chevrotain/regexp-to-ast@11.0.3", "", {}, "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA=="], "@chevrotain/regexp-to-ast": ["@chevrotain/regexp-to-ast@11.0.3", "", {}, "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA=="],
"@chevrotain/types": ["@chevrotain/types@11.0.3", "", {}, "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ=="], "@chevrotain/types": ["@chevrotain/types@11.1.2", "", {}, "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw=="],
"@chevrotain/utils": ["@chevrotain/utils@11.0.3", "", {}, "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ=="], "@chevrotain/utils": ["@chevrotain/utils@11.0.3", "", {}, "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ=="],
"@excalidraw/excalidraw": ["@excalidraw/excalidraw@0.18.0", "", { "dependencies": { "@braintree/sanitize-url": "6.0.2", "@excalidraw/laser-pointer": "1.3.1", "@excalidraw/mermaid-to-excalidraw": "1.1.2", "@excalidraw/random-username": "1.1.0", "@radix-ui/react-popover": "1.1.6", "@radix-ui/react-tabs": "1.0.2", "browser-fs-access": "0.29.1", "canvas-roundrect-polyfill": "0.0.1", "clsx": "1.1.1", "cross-env": "7.0.3", "es6-promise-pool": "2.5.0", "fractional-indexing": "3.2.0", "fuzzy": "0.1.3", "image-blob-reduce": "3.0.1", "jotai": "2.11.0", "jotai-scope": "0.7.2", "lodash.debounce": "4.0.8", "lodash.throttle": "4.1.1", "nanoid": "3.3.3", "open-color": "1.9.1", "pako": "2.0.3", "perfect-freehand": "1.2.0", "pica": "7.1.1", "png-chunk-text": "1.0.0", "png-chunks-encode": "1.0.0", "png-chunks-extract": "1.0.0", "points-on-curve": "1.0.1", "pwacompat": "2.0.17", "roughjs": "4.6.4", "sass": "1.51.0", "tunnel-rat": "0.1.2" }, "peerDependencies": { "react": "^17.0.2 || ^18.2.0 || ^19.0.0", "react-dom": "^17.0.2 || ^18.2.0 || ^19.0.0" } }, "sha512-QkIiS+5qdy8lmDWTKsuy0sK/fen/LRDtbhm2lc2xcFcqhv2/zdg95bYnl+wnwwXGHo7kEmP65BSiMHE7PJ3Zpw=="], "@excalidraw/excalidraw": ["@excalidraw/excalidraw@0.18.1", "", { "dependencies": { "@braintree/sanitize-url": "6.0.2", "@excalidraw/laser-pointer": "1.3.1", "@excalidraw/mermaid-to-excalidraw": "2.2.2", "@excalidraw/random-username": "1.1.0", "@radix-ui/react-popover": "1.1.6", "@radix-ui/react-tabs": "1.0.2", "browser-fs-access": "0.29.1", "canvas-roundrect-polyfill": "0.0.1", "clsx": "1.1.1", "cross-env": "7.0.3", "es6-promise-pool": "2.5.0", "fractional-indexing": "3.2.0", "fuzzy": "0.1.3", "image-blob-reduce": "3.0.1", "jotai": "2.11.0", "jotai-scope": "0.7.2", "lodash.debounce": "4.0.8", "lodash.throttle": "4.1.1", "nanoid": "3.3.3", "open-color": "1.9.1", "pako": "2.0.3", "perfect-freehand": "1.2.0", "pica": "7.1.1", "png-chunk-text": "1.0.0", "png-chunks-encode": "1.0.0", "png-chunks-extract": "1.0.0", "points-on-curve": "1.0.1", "pwacompat": "2.0.17", "roughjs": "4.6.4", "sass": "1.51.0", "tunnel-rat": "0.1.2" }, "peerDependencies": { "react": "^17.0.2 || ^18.2.0 || ^19.0.0", "react-dom": "^17.0.2 || ^18.2.0 || ^19.0.0" } }, "sha512-6i5Gt7IDTOH//qa0Z315Ly5iVRhjWpu2whrlQFqkuwrkKUWgRsMk0P5qdE7bpyDpai7jeLeWYkyj1eVAfni1lw=="],
"@excalidraw/laser-pointer": ["@excalidraw/laser-pointer@1.3.1", "", {}, "sha512-psA1z1N2qeAfsORdXc9JmD2y4CmDwmuMRxnNdJHZexIcPwaNEyIpNcelw+QkL9rz9tosaN9krXuKaRqYpRAR6g=="], "@excalidraw/laser-pointer": ["@excalidraw/laser-pointer@1.3.1", "", {}, "sha512-psA1z1N2qeAfsORdXc9JmD2y4CmDwmuMRxnNdJHZexIcPwaNEyIpNcelw+QkL9rz9tosaN9krXuKaRqYpRAR6g=="],
"@excalidraw/markdown-to-text": ["@excalidraw/markdown-to-text@0.1.2", "", {}, "sha512-1nDXBNAojfi3oSFwJswKREkFm5wrSjqay81QlyRv2pkITG/XYB5v+oChENVBQLcxQwX4IUATWvXM5BcaNhPiIg=="], "@excalidraw/markdown-to-text": ["@excalidraw/markdown-to-text@0.1.2", "", {}, "sha512-1nDXBNAojfi3oSFwJswKREkFm5wrSjqay81QlyRv2pkITG/XYB5v+oChENVBQLcxQwX4IUATWvXM5BcaNhPiIg=="],
"@excalidraw/mermaid-to-excalidraw": ["@excalidraw/mermaid-to-excalidraw@1.1.2", "", { "dependencies": { "@excalidraw/markdown-to-text": "0.1.2", "mermaid": "10.9.3", "nanoid": "4.0.2" } }, "sha512-hAFv/TTIsOdoy0dL5v+oBd297SQ+Z88gZ5u99fCIFuEMHfQuPgLhU/ztKhFSTs7fISwVo6fizny/5oQRR3d4tQ=="], "@excalidraw/mermaid-to-excalidraw": ["@excalidraw/mermaid-to-excalidraw@2.2.2", "", { "dependencies": { "@excalidraw/markdown-to-text": "0.1.2", "@mermaid-js/parser": "^0.6.3", "mermaid": "^11.12.1", "nanoid": "4.0.2" } }, "sha512-5VKQq5CdRocC82vOIUpQ5ufJOVV9FpBTdHGA+ULqazeIVV+cr299877omQCibsdS3Bpitz2fsnTwnIXEmLVDSg=="],
"@excalidraw/random-username": ["@excalidraw/random-username@1.1.0", "", {}, "sha512-nULYsQxkWHnbmHvcs+efMkJ4/9TtvNyFeLyHdeGxW0zHs6P+jYVqcRff9A6Vq9w9JXeDRnRh2VKvTtS19GW2qA=="], "@excalidraw/random-username": ["@excalidraw/random-username@1.1.0", "", {}, "sha512-nULYsQxkWHnbmHvcs+efMkJ4/9TtvNyFeLyHdeGxW0zHs6P+jYVqcRff9A6Vq9w9JXeDRnRh2VKvTtS19GW2qA=="],
@@ -166,17 +171,11 @@
"@types/d3-zoom": ["@types/d3-zoom@3.0.8", "", { "dependencies": { "@types/d3-interpolate": "*", "@types/d3-selection": "*" } }, "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw=="], "@types/d3-zoom": ["@types/d3-zoom@3.0.8", "", { "dependencies": { "@types/d3-interpolate": "*", "@types/d3-selection": "*" } }, "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw=="],
"@types/debug": ["@types/debug@4.1.13", "", { "dependencies": { "@types/ms": "*" } }, "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw=="],
"@types/geojson": ["@types/geojson@7946.0.16", "", {}, "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg=="], "@types/geojson": ["@types/geojson@7946.0.16", "", {}, "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg=="],
"@types/mdast": ["@types/mdast@3.0.15", "", { "dependencies": { "@types/unist": "^2" } }, "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ=="],
"@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
"@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
"@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], "@upsetjs/venn.js": ["@upsetjs/venn.js@2.0.0", "", { "optionalDependencies": { "d3-selection": "^3.0.0", "d3-transition": "^3.0.1" } }, "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw=="],
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
@@ -190,8 +189,6 @@
"canvas-roundrect-polyfill": ["canvas-roundrect-polyfill@0.0.1", "", {}, "sha512-yWq+R3U3jE+coOeEb3a3GgE2j/0MMiDKM/QpLb6h9ihf5fGY9UXtvK9o4vNqjWXoZz7/3EaSVU3IX53TvFFUOw=="], "canvas-roundrect-polyfill": ["canvas-roundrect-polyfill@0.0.1", "", {}, "sha512-yWq+R3U3jE+coOeEb3a3GgE2j/0MMiDKM/QpLb6h9ihf5fGY9UXtvK9o4vNqjWXoZz7/3EaSVU3IX53TvFFUOw=="],
"character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="],
"chevrotain": ["chevrotain@11.0.3", "", { "dependencies": { "@chevrotain/cst-dts-gen": "11.0.3", "@chevrotain/gast": "11.0.3", "@chevrotain/regexp-to-ast": "11.0.3", "@chevrotain/types": "11.0.3", "@chevrotain/utils": "11.0.3", "lodash-es": "4.17.21" } }, "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw=="], "chevrotain": ["chevrotain@11.0.3", "", { "dependencies": { "@chevrotain/cst-dts-gen": "11.0.3", "@chevrotain/gast": "11.0.3", "@chevrotain/regexp-to-ast": "11.0.3", "@chevrotain/types": "11.0.3", "@chevrotain/utils": "11.0.3", "lodash-es": "4.17.21" } }, "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw=="],
"chevrotain-allstar": ["chevrotain-allstar@0.3.1", "", { "dependencies": { "lodash-es": "^4.17.21" }, "peerDependencies": { "chevrotain": "^11.0.0" } }, "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw=="], "chevrotain-allstar": ["chevrotain-allstar@0.3.1", "", { "dependencies": { "lodash-es": "^4.17.21" }, "peerDependencies": { "chevrotain": "^11.0.0" } }, "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw=="],
@@ -280,25 +277,17 @@
"d3-zoom": ["d3-zoom@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", "d3-interpolate": "1 - 3", "d3-selection": "2 - 3", "d3-transition": "2 - 3" } }, "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw=="], "d3-zoom": ["d3-zoom@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", "d3-interpolate": "1 - 3", "d3-selection": "2 - 3", "d3-transition": "2 - 3" } }, "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw=="],
"dagre-d3-es": ["dagre-d3-es@7.0.13", "", { "dependencies": { "d3": "^7.9.0", "lodash-es": "^4.17.21" } }, "sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q=="], "dagre-d3-es": ["dagre-d3-es@7.0.14", "", { "dependencies": { "d3": "^7.9.0", "lodash-es": "^4.17.21" } }, "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg=="],
"dayjs": ["dayjs@1.11.21", "", {}, "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA=="], "dayjs": ["dayjs@1.11.21", "", {}, "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA=="],
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
"decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="],
"delaunator": ["delaunator@5.1.0", "", { "dependencies": { "robust-predicates": "^3.0.2" } }, "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ=="], "delaunator": ["delaunator@5.1.0", "", { "dependencies": { "robust-predicates": "^3.0.2" } }, "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ=="],
"dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
"detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="],
"diff": ["diff@5.2.2", "", {}, "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A=="], "dompurify": ["dompurify@3.4.11", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-zhlUV12GsaRzMsf9q5M254YhA4+VuF0fG+QFqu6aYpoGlKtz+w8//jBcGVYBgQkR5GHjUomejY84AV+/uPbWdw=="],
"dompurify": ["dompurify@3.4.9", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-4dPSRMRDqHvs0V4YDFCsaIZo4if5u0xM+llyxiM2fwuZFdKArUBAF3VtI2+n8NKg9P870WMdYk0UhqQNoWXbfQ=="], "es-toolkit": ["es-toolkit@1.49.0", "", {}, "sha512-G5iZ6Pc/FNRY/soKZHC+TxGDD83rHUDXxzaWhGCX44vAv/tMs56WMusnm/KMNK+luUPsgA9U28cGr4RDlSzL2g=="],
"elkjs": ["elkjs@0.9.3", "", {}, "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ=="],
"es6-promise-pool": ["es6-promise-pool@2.5.0", "", {}, "sha512-VHErXfzR/6r/+yyzPKeBvO0lgjfC5cbDCQWjWwMZWSb6YU39TGIl51OUmCfWCq4ylMdJSB8zkz2vIuIeIxXApA=="], "es6-promise-pool": ["es6-promise-pool@2.5.0", "", {}, "sha512-VHErXfzR/6r/+yyzPKeBvO0lgjfC5cbDCQWjWwMZWSb6YU39TGIl51OUmCfWCq4ylMdJSB8zkz2vIuIeIxXApA=="],
@@ -350,8 +339,6 @@
"khroma": ["khroma@2.1.0", "", {}, "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw=="], "khroma": ["khroma@2.1.0", "", {}, "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw=="],
"kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
"langium": ["langium@3.3.1", "", { "dependencies": { "chevrotain": "~11.0.3", "chevrotain-allstar": "~0.3.0", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.0.8" } }, "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w=="], "langium": ["langium@3.3.1", "", { "dependencies": { "chevrotain": "~11.0.3", "chevrotain-allstar": "~0.3.0", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.0.8" } }, "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w=="],
"layout-base": ["layout-base@1.0.2", "", {}, "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg=="], "layout-base": ["layout-base@1.0.2", "", {}, "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg=="],
@@ -366,63 +353,11 @@
"marked": ["marked@16.4.2", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA=="], "marked": ["marked@16.4.2", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA=="],
"mdast-util-from-markdown": ["mdast-util-from-markdown@1.3.1", "", { "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", "decode-named-character-reference": "^1.0.0", "mdast-util-to-string": "^3.1.0", "micromark": "^3.0.0", "micromark-util-decode-numeric-character-reference": "^1.0.0", "micromark-util-decode-string": "^1.0.0", "micromark-util-normalize-identifier": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0", "unist-util-stringify-position": "^3.0.0", "uvu": "^0.5.0" } }, "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww=="], "mermaid": ["mermaid@11.16.0", "", { "dependencies": { "@braintree/sanitize-url": "^7.1.2", "@iconify/utils": "^3.0.2", "@mermaid-js/parser": "^1.2.0", "@types/d3": "^7.4.3", "@upsetjs/venn.js": "^2.0.0", "cytoscape": "^3.33.3", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.14", "dayjs": "^1.11.20", "dompurify": "^3.3.3", "es-toolkit": "^1.45.1", "katex": "^0.16.45", "khroma": "^2.1.0", "marked": "^16.3.0", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0 || ^12 || ^13 || ^14.0.0" } }, "sha512-Zvm3kbstgdpvIJPPItlL7fppIZ3kibvc1oZIGxdvk9t6UFz6flv+Jw7FtRGKwfcI8OckmH04LqG6LlS6X4B1pA=="],
"mdast-util-to-string": ["mdast-util-to-string@3.2.0", "", { "dependencies": { "@types/mdast": "^3.0.0" } }, "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg=="],
"mermaid": ["mermaid@11.12.2", "", { "dependencies": { "@braintree/sanitize-url": "^7.1.1", "@iconify/utils": "^3.0.1", "@mermaid-js/parser": "^0.6.3", "@types/d3": "^7.4.3", "cytoscape": "^3.29.3", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.13", "dayjs": "^1.11.18", "dompurify": "^3.2.5", "katex": "^0.16.22", "khroma": "^2.1.0", "lodash-es": "^4.17.21", "marked": "^16.2.1", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0" } }, "sha512-n34QPDPEKmaeCG4WDMGy0OT6PSyxKCfy2pJgShP+Qow2KLrvWjclwbc3yXfSIf4BanqWEhQEpngWwNp/XhZt6w=="],
"micromark": ["micromark@3.2.0", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "micromark-core-commonmark": "^1.0.1", "micromark-factory-space": "^1.0.0", "micromark-util-character": "^1.0.0", "micromark-util-chunked": "^1.0.0", "micromark-util-combine-extensions": "^1.0.0", "micromark-util-decode-numeric-character-reference": "^1.0.0", "micromark-util-encode": "^1.0.0", "micromark-util-normalize-identifier": "^1.0.0", "micromark-util-resolve-all": "^1.0.0", "micromark-util-sanitize-uri": "^1.0.0", "micromark-util-subtokenize": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.1", "uvu": "^0.5.0" } }, "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA=="],
"micromark-core-commonmark": ["micromark-core-commonmark@1.1.0", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-factory-destination": "^1.0.0", "micromark-factory-label": "^1.0.0", "micromark-factory-space": "^1.0.0", "micromark-factory-title": "^1.0.0", "micromark-factory-whitespace": "^1.0.0", "micromark-util-character": "^1.0.0", "micromark-util-chunked": "^1.0.0", "micromark-util-classify-character": "^1.0.0", "micromark-util-html-tag-name": "^1.0.0", "micromark-util-normalize-identifier": "^1.0.0", "micromark-util-resolve-all": "^1.0.0", "micromark-util-subtokenize": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.1", "uvu": "^0.5.0" } }, "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw=="],
"micromark-factory-destination": ["micromark-factory-destination@1.1.0", "", { "dependencies": { "micromark-util-character": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0" } }, "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg=="],
"micromark-factory-label": ["micromark-factory-label@1.1.0", "", { "dependencies": { "micromark-util-character": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0", "uvu": "^0.5.0" } }, "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w=="],
"micromark-factory-space": ["micromark-factory-space@1.1.0", "", { "dependencies": { "micromark-util-character": "^1.0.0", "micromark-util-types": "^1.0.0" } }, "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ=="],
"micromark-factory-title": ["micromark-factory-title@1.1.0", "", { "dependencies": { "micromark-factory-space": "^1.0.0", "micromark-util-character": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0" } }, "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ=="],
"micromark-factory-whitespace": ["micromark-factory-whitespace@1.1.0", "", { "dependencies": { "micromark-factory-space": "^1.0.0", "micromark-util-character": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0" } }, "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ=="],
"micromark-util-character": ["micromark-util-character@1.2.0", "", { "dependencies": { "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0" } }, "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg=="],
"micromark-util-chunked": ["micromark-util-chunked@1.1.0", "", { "dependencies": { "micromark-util-symbol": "^1.0.0" } }, "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ=="],
"micromark-util-classify-character": ["micromark-util-classify-character@1.1.0", "", { "dependencies": { "micromark-util-character": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0" } }, "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw=="],
"micromark-util-combine-extensions": ["micromark-util-combine-extensions@1.1.0", "", { "dependencies": { "micromark-util-chunked": "^1.0.0", "micromark-util-types": "^1.0.0" } }, "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA=="],
"micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@1.1.0", "", { "dependencies": { "micromark-util-symbol": "^1.0.0" } }, "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw=="],
"micromark-util-decode-string": ["micromark-util-decode-string@1.1.0", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^1.0.0", "micromark-util-decode-numeric-character-reference": "^1.0.0", "micromark-util-symbol": "^1.0.0" } }, "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ=="],
"micromark-util-encode": ["micromark-util-encode@1.1.0", "", {}, "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw=="],
"micromark-util-html-tag-name": ["micromark-util-html-tag-name@1.2.0", "", {}, "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q=="],
"micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@1.1.0", "", { "dependencies": { "micromark-util-symbol": "^1.0.0" } }, "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q=="],
"micromark-util-resolve-all": ["micromark-util-resolve-all@1.1.0", "", { "dependencies": { "micromark-util-types": "^1.0.0" } }, "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA=="],
"micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@1.2.0", "", { "dependencies": { "micromark-util-character": "^1.0.0", "micromark-util-encode": "^1.0.0", "micromark-util-symbol": "^1.0.0" } }, "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A=="],
"micromark-util-subtokenize": ["micromark-util-subtokenize@1.1.0", "", { "dependencies": { "micromark-util-chunked": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0", "uvu": "^0.5.0" } }, "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A=="],
"micromark-util-symbol": ["micromark-util-symbol@1.1.0", "", {}, "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag=="],
"micromark-util-types": ["micromark-util-types@1.1.0", "", {}, "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg=="],
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"multimath": ["multimath@2.0.0", "", { "dependencies": { "glur": "^1.1.2", "object-assign": "^4.1.1" } }, "sha512-toRx66cAMJ+Ccz7pMIg38xSIrtnbozk0dchXezwQDMgQmbGpfxjtv68H+L00iFL8hxDaVjrmwAFSb3I6bg8Q2g=="], "multimath": ["multimath@2.0.0", "", { "dependencies": { "glur": "^1.1.2", "object-assign": "^4.1.1" } }, "sha512-toRx66cAMJ+Ccz7pMIg38xSIrtnbozk0dchXezwQDMgQmbGpfxjtv68H+L00iFL8hxDaVjrmwAFSb3I6bg8Q2g=="],
"nanoid": ["nanoid@3.3.3", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w=="], "nanoid": ["nanoid@5.0.9", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q=="],
"non-layered-tidy-tree-layout": ["non-layered-tidy-tree-layout@2.0.2", "", {}, "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw=="],
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
@@ -474,8 +409,6 @@
"rw": ["rw@1.3.3", "", {}, "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="], "rw": ["rw@1.3.3", "", {}, "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="],
"sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="],
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
"sass": ["sass@1.51.0", "", { "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", "source-map-js": ">=0.6.2 <2.0.0" }, "bin": { "sass": "sass.js" } }, "sha512-haGdpTgywJTvHC2b91GSq+clTKGbtkkZmVAb82jZQN/wTy6qs8DdFm2lhEQbEwrY0QDRgSQ3xDurqM977C3noA=="], "sass": ["sass@1.51.0", "", { "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", "source-map-js": ">=0.6.2 <2.0.0" }, "bin": { "sass": "sass.js" } }, "sha512-haGdpTgywJTvHC2b91GSq+clTKGbtkkZmVAb82jZQN/wTy6qs8DdFm2lhEQbEwrY0QDRgSQ3xDurqM977C3noA=="],
@@ -502,8 +435,6 @@
"tunnel-rat": ["tunnel-rat@0.1.2", "", { "dependencies": { "zustand": "^4.3.2" } }, "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ=="], "tunnel-rat": ["tunnel-rat@0.1.2", "", { "dependencies": { "zustand": "^4.3.2" } }, "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ=="],
"unist-util-stringify-position": ["unist-util-stringify-position@3.0.3", "", { "dependencies": { "@types/unist": "^2.0.0" } }, "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg=="],
"use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="],
"use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="], "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="],
@@ -512,8 +443,6 @@
"uuid": ["uuid@11.1.1", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ=="], "uuid": ["uuid@11.1.1", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ=="],
"uvu": ["uvu@0.5.6", "", { "dependencies": { "dequal": "^2.0.0", "diff": "^5.0.0", "kleur": "^4.0.3", "sade": "^1.7.3" }, "bin": { "uvu": "bin.js" } }, "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA=="],
"vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="], "vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="],
"vscode-languageserver": ["vscode-languageserver@9.0.1", "", { "dependencies": { "vscode-languageserver-protocol": "3.17.5" }, "bin": { "installServerIntoExtension": "bin/installServerIntoExtension" } }, "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g=="], "vscode-languageserver": ["vscode-languageserver@9.0.1", "", { "dependencies": { "vscode-languageserver-protocol": "3.17.5" }, "bin": { "installServerIntoExtension": "bin/installServerIntoExtension" } }, "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g=="],
@@ -526,21 +455,15 @@
"vscode-uri": ["vscode-uri@3.0.8", "", {}, "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw=="], "vscode-uri": ["vscode-uri@3.0.8", "", {}, "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw=="],
"web-worker": ["web-worker@1.5.0", "", {}, "sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw=="],
"webworkify": ["webworkify@1.5.0", "", {}, "sha512-AMcUeyXAhbACL8S2hqqdqOLqvJ8ylmIbNwUIqQujRSouf4+eUFaXbG6F1Rbu+srlJMmxQWsiU7mOJi0nMBfM1g=="], "webworkify": ["webworkify@1.5.0", "", {}, "sha512-AMcUeyXAhbACL8S2hqqdqOLqvJ8ylmIbNwUIqQujRSouf4+eUFaXbG6F1Rbu+srlJMmxQWsiU7mOJi0nMBfM1g=="],
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
"zustand": ["zustand@4.5.7", "", { "dependencies": { "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "@types/react": ">=16.8", "immer": ">=9.0.6", "react": ">=16.8" }, "optionalPeers": ["@types/react", "immer", "react"] }, "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw=="], "zustand": ["zustand@4.5.7", "", { "dependencies": { "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "@types/react": ">=16.8", "immer": ">=9.0.6", "react": ">=16.8" }, "optionalPeers": ["@types/react", "immer", "react"] }, "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw=="],
"@chevrotain/cst-dts-gen/lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], "@chevrotain/cst-dts-gen/@chevrotain/types": ["@chevrotain/types@11.0.3", "", {}, "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ=="],
"@chevrotain/gast/lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], "@chevrotain/gast/@chevrotain/types": ["@chevrotain/types@11.0.3", "", {}, "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ=="],
"@excalidraw/mermaid-to-excalidraw/mermaid": ["mermaid@10.9.3", "", { "dependencies": { "@braintree/sanitize-url": "^6.0.1", "@types/d3-scale": "^4.0.3", "@types/d3-scale-chromatic": "^3.0.0", "cytoscape": "^3.28.1", "cytoscape-cose-bilkent": "^4.1.0", "d3": "^7.4.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.10", "dayjs": "^1.11.7", "dompurify": "^3.0.5 <3.1.7", "elkjs": "^0.9.0", "katex": "^0.16.9", "khroma": "^2.0.0", "lodash-es": "^4.17.21", "mdast-util-from-markdown": "^1.3.0", "non-layered-tidy-tree-layout": "^2.0.2", "stylis": "^4.1.3", "ts-dedent": "^2.2.0", "uuid": "^9.0.0", "web-worker": "^1.2.0" } }, "sha512-V80X1isSEvAewIL3xhmz/rVmc27CVljcsbWxkxlWJWY/1kQa4XOABqpDl2qQLGKzpKm6WbTfUEKImBlUfFYArw=="],
"@excalidraw/mermaid-to-excalidraw/nanoid": ["nanoid@4.0.2", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw=="],
"@radix-ui/react-collection/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA=="], "@radix-ui/react-collection/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA=="],
@@ -576,7 +499,7 @@
"@radix-ui/react-tabs/@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg=="], "@radix-ui/react-tabs/@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg=="],
"chevrotain/lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], "chevrotain/@chevrotain/types": ["@chevrotain/types@11.0.3", "", {}, "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ=="],
"cytoscape-fcose/cose-base": ["cose-base@2.2.0", "", { "dependencies": { "layout-base": "^2.0.0" } }, "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g=="], "cytoscape-fcose/cose-base": ["cose-base@2.2.0", "", { "dependencies": { "layout-base": "^2.0.0" } }, "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g=="],
@@ -588,18 +511,14 @@
"mermaid/@braintree/sanitize-url": ["@braintree/sanitize-url@7.1.2", "", {}, "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA=="], "mermaid/@braintree/sanitize-url": ["@braintree/sanitize-url@7.1.2", "", {}, "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA=="],
"mermaid/@mermaid-js/parser": ["@mermaid-js/parser@1.2.0", "", { "dependencies": { "@chevrotain/types": "~11.1.2" } }, "sha512-oYPyv8A4As1yH5Bx+04iQEQxXuIQDe0GKCNSRgao6z8AM9jixXIfP0vsppRLvGf+nKIOb9/LdpWA4YuJiVvESA=="],
"mermaid/roughjs": ["roughjs@4.6.6", "", { "dependencies": { "hachure-fill": "^0.5.2", "path-data-parser": "^0.1.0", "points-on-curve": "^0.2.0", "points-on-path": "^0.2.1" } }, "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ=="], "mermaid/roughjs": ["roughjs@4.6.6", "", { "dependencies": { "hachure-fill": "^0.5.2", "path-data-parser": "^0.1.0", "points-on-curve": "^0.2.0", "points-on-path": "^0.2.1" } }, "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ=="],
"points-on-path/points-on-curve": ["points-on-curve@0.2.0", "", {}, "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A=="], "points-on-path/points-on-curve": ["points-on-curve@0.2.0", "", {}, "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A=="],
"roughjs/points-on-curve": ["points-on-curve@0.2.0", "", {}, "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A=="], "roughjs/points-on-curve": ["points-on-curve@0.2.0", "", {}, "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A=="],
"@excalidraw/mermaid-to-excalidraw/mermaid/dagre-d3-es": ["dagre-d3-es@7.0.10", "", { "dependencies": { "d3": "^7.8.2", "lodash-es": "^4.17.21" } }, "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A=="],
"@excalidraw/mermaid-to-excalidraw/mermaid/dompurify": ["dompurify@3.1.6", "", {}, "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ=="],
"@excalidraw/mermaid-to-excalidraw/mermaid/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="],
"@radix-ui/react-roving-focus/@radix-ui/react-id/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ=="], "@radix-ui/react-roving-focus/@radix-ui/react-id/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ=="],
"@radix-ui/react-roving-focus/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw=="], "@radix-ui/react-roving-focus/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw=="],
+6 -6
View File
@@ -1,13 +1,13 @@
{ {
"name": "gstack-diagram-render", "name": "gstack-diagram-render",
"sha256": "da9c363071afbe79e06807bd1e67dbacc1123187db7b99e2608dd4a1a9567e94", "sha256": "90148189fc8688870cbb822593112b5621bcbf265f4c44f363598390e665d329",
"srcSha256": "07238fae312bc0444f62b0a0a3404a8a38c45cef505aa1528c60a0ded17cbe06", "srcSha256": "07238fae312bc0444f62b0a0a3404a8a38c45cef505aa1528c60a0ded17cbe06",
"bytes": 9645479, "bytes": 7953601,
"bunVersion": "1.3.13", "bunVersion": "1.3.14",
"deps": { "deps": {
"@excalidraw/excalidraw": "0.18.0", "@excalidraw/excalidraw": "0.18.1",
"@excalidraw/mermaid-to-excalidraw": "1.1.2", "@excalidraw/mermaid-to-excalidraw": "2.2.2",
"mermaid": "11.12.2", "mermaid": "11.16.0",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1" "react-dom": "18.3.1"
} }
+1694 -2639
View File
File diff suppressed because one or more lines are too long
+8 -3
View File
@@ -7,10 +7,15 @@
"build": "bun run scripts/build.ts" "build": "bun run scripts/build.ts"
}, },
"dependencies": { "dependencies": {
"@excalidraw/excalidraw": "0.18.0", "@excalidraw/excalidraw": "0.18.1",
"@excalidraw/mermaid-to-excalidraw": "1.1.2", "@excalidraw/mermaid-to-excalidraw": "2.2.2",
"mermaid": "11.12.2", "mermaid": "11.16.0",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1" "react-dom": "18.3.1"
},
"overrides": {
"dompurify": "3.4.11",
"lodash-es": "4.18.1",
"nanoid": "5.0.9"
} }
} }
+15 -6
View File
@@ -36,7 +36,7 @@
"server": "bun run browse/src/server.ts", "server": "bun run browse/src/server.ts",
"test": "bun run scripts/test-free-strict.ts", "test": "bun run scripts/test-free-strict.ts",
"check:gstack2-generated": "bun run scripts/gstack2/check-generated.ts", "check:gstack2-generated": "bun run scripts/gstack2/check-generated.ts",
"test:gstack2": "bun run gen:gstack2 && bun run check:gstack2-generated && bun test --timeout 60000 test/gstack2-*.test.ts", "test:gstack2": "bun run gen:gstack2 && bun run check:gstack2-generated && bun run scripts/gstack2/test-suite.ts",
"test:gstack2:install": "bun run scripts/gstack2/test-install-matrix.ts --full", "test:gstack2:install": "bun run scripts/gstack2/test-install-matrix.ts --full",
"test:gstack2:parity": "bun run ensure:gstack2-runtime && bun run scripts/gstack2/run-parity.ts", "test:gstack2:parity": "bun run ensure:gstack2-runtime && bun run scripts/gstack2/run-parity.ts",
"test:free": "bun run scripts/test-free-shards.ts", "test:free": "bun run scripts/test-free-shards.ts",
@@ -70,17 +70,26 @@
"slop:diff": "bun run scripts/slop-diff.ts" "slop:diff": "bun run scripts/slop-diff.ts"
}, },
"dependencies": { "dependencies": {
"@anthropic-ai/sdk": "^0.78.0", "@anthropic-ai/sdk": "^0.112.4",
"@ngrok/ngrok": "^1.7.0", "@ngrok/ngrok": "^1.7.0",
"diff": "^9.0.0", "diff": "^9.0.0",
"html-to-docx": "1.8.0", "html-to-docx": "1.8.0",
"marked": "^18.0.2", "marked": "^18.0.6",
"playwright": "npm:playwright-core@^1.58.2", "playwright": "npm:playwright-core@^1.58.2",
"sharp": "^0.34.5", "sharp": "^0.34.5",
"socks": "^2.8.8", "socks": "^2.8.9",
"xterm": "5", "xterm": "5",
"xterm-addon-fit": "^0.8.0" "xterm-addon-fit": "^0.8.0"
}, },
"overrides": {
"@protobufjs/utf8": "1.1.1",
"adm-zip": "0.6.0",
"fast-uri": "3.1.3",
"hono": "4.12.27",
"ip-address": "10.2.0",
"protobufjs": "7.6.5",
"qs": "6.15.2"
},
"engines": { "engines": {
"bun": ">=1.0.0", "bun": ">=1.0.0",
"node": ">=18.0.0" "node": ">=18.0.0"
@@ -96,7 +105,7 @@
"devtools" "devtools"
], ],
"devDependencies": { "devDependencies": {
"@anthropic-ai/claude-agent-sdk": "0.2.117", "@anthropic-ai/claude-agent-sdk": "0.3.216",
"@huggingface/transformers": "^4.1.0" "@huggingface/transformers": "4.2.0"
} }
} }
+128 -12
View File
@@ -27,7 +27,12 @@ import {
runExternalEffect, runExternalEffect,
updateRunWorkflow, updateRunWorkflow,
} from "./state.js"; } from "./state.js";
import { runDoctor, formatDoctor } from "./doctor.js"; import {
CAPABILITY_READINESS_CAPABILITIES,
capabilityReadiness,
runDoctor,
formatDoctor,
} from "./doctor.js";
import { cleanupRuntime } from "./cleanup.js"; import { cleanupRuntime } from "./cleanup.js";
import { import {
ContextClient, ContextClient,
@@ -41,6 +46,11 @@ import { installManagedRuntime, uninstallManagedRuntime } from "./install.js";
import { assertManagedHome, withRuntimeLifecycleLock } from "./managed-home.js"; import { assertManagedHome, withRuntimeLifecycleLock } from "./managed-home.js";
import { errorWithCode as cliError } from "./errors.js"; import { errorWithCode as cliError } from "./errors.js";
import { RUNTIME_VERSION } from "./index.js"; import { RUNTIME_VERSION } from "./index.js";
import {
EXECUTION_RESULT_ERROR_CODES,
executionResult,
renderExecutionResult,
} from "./execution-result.js";
export async function main(argv = process.argv.slice(2), options = {}) { export async function main(argv = process.argv.slice(2), options = {}) {
const env = options.env ?? process.env; const env = options.env ?? process.env;
@@ -90,6 +100,11 @@ export async function main(argv = process.argv.slice(2), options = {}) {
throw cliError(`Unknown command: ${command}`, "USAGE"); throw cliError(`Unknown command: ${command}`, "USAGE");
} }
} catch (error) { } catch (error) {
const structuredResult = error?.executionResult ?? error?.cause?.executionResult;
if (structuredResult) {
write(stderr, renderExecutionResult(structuredResult, { json: true }));
return 1;
}
const json = args.includes("--json"); const json = args.includes("--json");
const safeMessage = redactSensitiveText(error?.message ?? String(error)); const safeMessage = redactSensitiveText(error?.message ?? String(error));
if (json) { if (json) {
@@ -154,11 +169,53 @@ async function initCommand({ args, home, cwd, stdout, legacyAlias = false }) {
} }
async function doctorCommand({ args, home, cwd, stdout }) { async function doctorCommand({ args, home, cwd, stdout }) {
const parsed = parseFlags(args, new Set(["--json", "--skill-api"])); const parsed = parseFlags(args, new Set(["--json", "--skill-api", "--capability"]));
if (parsed.positionals.length) throw cliError("Doctor accepts only named options", "USAGE"); if (parsed.positionals.length) throw cliError("Doctor accepts only named options", "USAGE");
const capability = parsed.values.get("--capability");
if (capability && !CAPABILITY_READINESS_CAPABILITIES.includes(capability)) {
throw cliError(`Unknown capability: ${capability}. Choose ${CAPABILITY_READINESS_CAPABILITIES.join(", ")}.`, "USAGE");
}
const report = await runDoctor({ home, cwd, expectedSkillApi: parsed.values.get("--skill-api") }); const report = await runDoctor({ home, cwd, expectedSkillApi: parsed.values.get("--skill-api") });
write(stdout, parsed.flags.has("--json") ? `${JSON.stringify(report, null, 2)}\n` : formatDoctor(report)); const result = capability ? capabilityReadiness(report, capability) : report;
return report.ok ? 0 : 1; if (capability) {
const envelope = capabilityExecutionResult(result);
write(stdout, renderExecutionResult(envelope, { json: parsed.flags.has("--json") }));
return envelope.status === "success" ? 0 : 1;
}
write(stdout, parsed.flags.has("--json")
? `${JSON.stringify(result, null, 2)}\n`
: formatDoctor(result));
return result.ok ? 0 : 1;
}
function capabilityExecutionResult(result) {
const statusByReadiness = {
ready: "success",
degraded: "degraded",
unavailable: "degraded",
unsupported: "unsupported",
failed: "failed",
};
const codeByReadiness = {
ready: null,
degraded: EXECUTION_RESULT_ERROR_CODES.DEGRADED,
unavailable: EXECUTION_RESULT_ERROR_CODES.CAPABILITY_UNAVAILABLE,
unsupported: EXECUTION_RESULT_ERROR_CODES.CAPABILITY_UNSUPPORTED,
failed: EXECUTION_RESULT_ERROR_CODES.CAPABILITY_FAILED,
};
const readiness = result.readiness.status;
const evidence = result.readiness.evidence?.map((item) =>
`${item.id}: ${item.status}${item.message}`) ?? [
`platform: ${result.platform.status}`,
`judgment: ${result.judgment.status}`,
];
return executionResult({
status: statusByReadiness[readiness],
code: codeByReadiness[readiness],
summary: result.readiness.message,
evidence,
data: result,
});
} }
async function configCommand({ args, home, cwd, stdout }) { async function configCommand({ args, home, cwd, stdout }) {
@@ -391,7 +448,7 @@ async function stateCommand({ args, home, cwd, env, stdout, stderr }) {
"EXTERNAL_EFFECT_UNCERTAIN", "EXTERNAL_EFFECT_UNCERTAIN",
); );
} }
write(stdout, `${JSON.stringify({ status: result.status, effectKey, idempotencyKey: result.idempotencyKey ?? null, result: result.result })}\n`); write(stdout, renderExecutionResult(result.result, { json: true }));
return 0; return 0;
} }
if (action === "reconcile-not-applied") { if (action === "reconcile-not-applied") {
@@ -423,6 +480,7 @@ async function stateCommand({ args, home, cwd, env, stdout, stderr }) {
} }
async function runExternalCommand(command, { cwd, env, stdout, stderr }) { async function runExternalCommand(command, { cwd, env, stdout, stderr }) {
const maxCapturedBytes = 1024 * 1024;
const [executable, ...args] = command; const [executable, ...args] = command;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const child = spawn(executable, args, { const child = spawn(executable, args, {
@@ -431,23 +489,81 @@ async function runExternalCommand(command, { cwd, env, stdout, stderr }) {
shell: false, shell: false,
stdio: ["inherit", "pipe", "pipe"], stdio: ["inherit", "pipe", "pipe"],
}); });
child.stdout?.on("data", (chunk) => write(stdout, chunk)); const captured = { stdout: "", stderr: "", bytes: 0, truncated: false };
child.stderr?.on("data", (chunk) => write(stderr, chunk)); const capture = (key, chunk) => {
const remaining = maxCapturedBytes - captured.bytes;
if (remaining <= 0) { captured.truncated = true; return; }
const buffer = Buffer.from(chunk);
captured[key] += buffer.subarray(0, remaining).toString();
captured.bytes += Math.min(buffer.length, remaining);
if (buffer.length > remaining) captured.truncated = true;
};
child.stdout?.on("data", (chunk) => capture("stdout", chunk));
child.stderr?.on("data", (chunk) => capture("stderr", chunk));
child.once("error", reject); child.once("error", reject);
child.once("close", (code, signal) => { child.once("close", (code, signal) => {
if (code === 0) { if (code === 0) {
resolve({ exitCode: 0, executable: path.basename(executable) }); if (captured.truncated) {
reject(executionResultError(
`External command ${path.basename(executable)} exceeded the ${maxCapturedBytes}-byte result limit; verify its side effect before reconciling it as applied.`,
EXECUTION_RESULT_ERROR_CODES.DEGRADED,
"degraded",
["output exceeded 1048576-byte capture limit"],
{ executable: path.basename(executable), exitCode: 0, truncated: true },
));
return;
}
const evidence = [];
if (captured.stdout.trim()) evidence.push("non-empty stdout");
if (captured.stderr.trim()) evidence.push("non-empty stderr");
const name = path.basename(executable);
if (evidence.length === 0) {
reject(executionResultError(
`External command ${name} exited 0 but produced no output; verify its side effect before reconciling it as applied.`,
EXECUTION_RESULT_ERROR_CODES.EMPTY,
"degraded",
["exit code 0", "stdout and stderr were empty"],
{ executable: name, exitCode: 0, stdout: "", stderr: "" },
));
return;
}
resolve(executionResult({
status: "success",
summary: `External command ${name} completed`,
evidence: [`exit code 0`, ...evidence],
data: {
exitCode: 0,
executable: name,
stdout: captured.stdout,
stderr: captured.stderr,
},
}));
return; return;
} }
const error = cliError( const error = executionResultError(
`External command ${path.basename(executable)} ${signal ? `ended by ${signal}` : `exited ${code}`}`, `External command ${path.basename(executable)} ${signal ? `ended by ${signal}` : `exited ${code}`}`,
"EXTERNAL_COMMAND_FAILED", EXECUTION_RESULT_ERROR_CODES.FAILED,
"failed",
[signal ? `terminated by signal ${signal}` : `exit code ${code}`],
{
executable: path.basename(executable),
exitCode: code,
signal: signal ?? null,
stdout: captured.stdout,
stderr: captured.stderr,
},
); );
reject(error); reject(error);
}); });
}); });
} }
function executionResultError(summary, code, status, evidence, data) {
const error = cliError(summary, code);
error.executionResult = executionResult({ status, code, summary, evidence, data });
return error;
}
async function withOwnedRuntimeMutation(home, callback) { async function withOwnedRuntimeMutation(home, callback) {
return withRuntimeLifecycleLock(home, async () => { return withRuntimeLifecycleLock(home, async () => {
await assertManagedHome(home); await assertManagedHome(home);
@@ -724,7 +840,7 @@ function parseFlags(args, allowed) {
continue; continue;
} }
if (!allowed.has(arg)) throw cliError(`Unknown option: ${arg}`, "USAGE"); if (!allowed.has(arg)) throw cliError(`Unknown option: ${arg}`, "USAGE");
if (["--source", "--version", "--url", "--older-than-hours", "--max-pages", "--max-depth", "--max-links", "--skill-api"].includes(arg)) { if (["--source", "--version", "--url", "--older-than-hours", "--max-pages", "--max-depth", "--max-links", "--skill-api", "--capability"].includes(arg)) {
const value = args[++index]; const value = args[++index];
if (value == null || value.startsWith("--")) throw cliError(`${arg} requires a value`, "USAGE"); if (value == null || value.startsWith("--")) throw cliError(`${arg} requires a value`, "USAGE");
values.set(arg, value); values.set(arg, value);
@@ -801,7 +917,7 @@ function usage() {
"Usage:\n" + "Usage:\n" +
" gstack init # initialize state only\n" + " gstack init # initialize state only\n" +
" gstack setup # compatibility alias for init\n" + " gstack setup # compatibility alias for init\n" +
" gstack doctor [--skill-api <version>] [--json]\n" + " gstack doctor [--capability browser|design|diagram|pdf|ios] [--skill-api <version>] [--json]\n" +
" gstack paths [--json|--shell]\n" + " gstack paths [--json|--shell]\n" +
" gstack runtime path <bundle-relative-path>\n" + " gstack runtime path <bundle-relative-path>\n" +
" gstack config get [key]\n" + " gstack config get [key]\n" +
+98
View File
@@ -18,6 +18,14 @@ import {
managedBunRelativePath, managedBunRelativePath,
} from "./install.js"; } from "./install.js";
export const CAPABILITY_READINESS_CAPABILITIES = Object.freeze([
"browser",
"design",
"diagram",
"pdf",
"ios",
]);
export async function runDoctor(options = {}) { export async function runDoctor(options = {}) {
const paths = resolveRuntimePaths(options); const paths = resolveRuntimePaths(options);
const checks = []; const checks = [];
@@ -209,6 +217,83 @@ export async function runDoctor(options = {}) {
}; };
} }
export function capabilityReadiness(report, capability, options = {}) {
if (!CAPABILITY_READINESS_CAPABILITIES.includes(capability)) {
throw new TypeError(`Unknown capability: ${capability}`);
}
const platform = options.platform ?? process.platform;
const checkedAt = report.checkedAt;
const judgment = {
status: "available",
message: "Pure-judgment skill guidance is available without the optional runtime.",
};
if (capability === "ios" && platform !== "darwin") {
return {
ok: false,
capability,
checkedAt,
judgment,
platform: { status: "unsupported", platform, message: "Physical iOS requires macOS and the existing CoreDevice harness." },
consent: {
preview: { status: "not-applicable", granted: false },
install: { status: "not-applicable", granted: false },
},
readiness: { status: "unsupported", message: "The runtime capability is unsupported on this platform." },
nextAction: "Continue with pure judgment or move the physical-iOS workflow to macOS.",
};
}
const capabilityCheck = report.checks.find((check) => check.id === `capability:${capability}`);
const runtimeCheck = report.checks.find((check) => check.id === "managed-runtime");
let status;
if (capabilityCheck?.status === "pass" && runtimeCheck?.status === "pass") status = "ready";
else if (capabilityCheck?.status === "pass" && runtimeCheck?.status === "warn") status = "degraded";
else if (capabilityCheck?.status === "pass") status = "failed";
else if (capabilityCheck?.status === "fail") status = "failed";
else status = "unavailable";
const needsSetup = status === "unavailable" || status === "failed";
const messages = {
ready: "The selected capability passed its runtime readiness checks.",
degraded: "The capability check passed, but the managed runtime reported a degraded condition.",
unavailable: "The optional runtime capability is not installed or cannot currently be inspected.",
failed: "The selected capability is installed but failed readiness checks.",
};
return {
ok: status === "ready" || status === "degraded",
capability,
checkedAt,
judgment,
platform: { status: "supported", platform },
consent: {
preview: {
status: needsSetup ? "required" : "not-required",
granted: false,
message: needsSetup
? "Consent is required before an uncached signed-manifest metadata preview; this command does not grant it."
: "No setup preview is needed for the current readiness state.",
},
install: {
status: needsSetup ? "required-after-preview" : "not-required",
granted: false,
message: needsSetup
? "Install consent is separate and may be requested only after the complete preview; this command does not grant it."
: "No install is needed for the current readiness state.",
},
},
readiness: {
status,
message: messages[status],
evidence: [runtimeCheck, capabilityCheck].filter(Boolean),
},
nextAction: needsSetup
? `Ask for preview consent, then run the packaged bootstrap preview for ${capability}; continue judgment-only work if setup is deferred.`
: status === "degraded"
? "Review the managed-runtime warning before capability-dependent evidence work."
: "Proceed with capability-dependent work.",
};
}
async function inspectRuntimeBun(activeRoot, manifest) { async function inspectRuntimeBun(activeRoot, manifest) {
const relative = managedBunRelativePath(); const relative = managedBunRelativePath();
const declared = manifest?.tools?.bun; const declared = manifest?.tools?.bun;
@@ -388,3 +473,16 @@ export function formatDoctor(report) {
for (const check of report.checks) lines.push(`${symbol[check.status]} ${check.id}: ${check.message}`); for (const check of report.checks) lines.push(`${symbol[check.status]} ${check.id}: ${check.message}`);
return `${lines.join("\n")}\n`; return `${lines.join("\n")}\n`;
} }
export function formatCapabilityReadiness(report) {
const lines = [
`gstack capability readiness: ${report.capability}`,
`judgment: ${report.judgment.status}`,
`platform: ${report.platform.status}`,
`preview consent: ${report.consent.preview.status}`,
`install consent: ${report.consent.install.status}`,
`readiness: ${report.readiness.status}`,
`next: ${report.nextAction}`,
];
return `${lines.join("\n")}\n`;
}
+92
View File
@@ -0,0 +1,92 @@
import { errorWithCode } from "./errors.js";
export const EXECUTION_RESULT_SCHEMA_VERSION = 1;
export const EXECUTION_RESULT_STATUSES = Object.freeze([
"success",
"degraded",
"unsupported",
"failed",
]);
export const EXECUTION_RESULT_ERROR_CODES = Object.freeze({
EMPTY: "EXECUTION_EMPTY",
MALFORMED: "EXECUTION_MALFORMED",
DEGRADED: "EXECUTION_DEGRADED",
UNSUPPORTED: "EXECUTION_UNSUPPORTED",
FAILED: "EXECUTION_FAILED",
CAPABILITY_UNAVAILABLE: "CAPABILITY_UNAVAILABLE",
CAPABILITY_UNSUPPORTED: "CAPABILITY_UNSUPPORTED",
CAPABILITY_FAILED: "CAPABILITY_FAILED",
});
export const EXECUTION_RESULT_SCHEMA = Object.freeze({
$schema: "https://json-schema.org/draft/2020-12/schema",
$id: "https://gstack.dev/schemas/execution-result-v1.json",
title: "GStack execution result",
type: "object",
additionalProperties: false,
required: ["schemaVersion", "status", "code", "summary", "evidence", "data"],
properties: {
schemaVersion: { const: EXECUTION_RESULT_SCHEMA_VERSION },
status: { enum: EXECUTION_RESULT_STATUSES },
code: { type: ["string", "null"], pattern: "^[A-Z][A-Z0-9_]{2,63}$" },
summary: { type: "string", minLength: 1 },
evidence: { type: "array", items: { type: "string", minLength: 1 } },
data: {},
},
allOf: [
{ if: { properties: { status: { const: "success" } } }, then: { properties: { code: { type: "null" }, evidence: { minItems: 1 } } } },
{ if: { properties: { status: { enum: ["degraded", "unsupported", "failed"] } } }, then: { properties: { code: { type: "string" } } } },
],
});
/** Validate the host-neutral result before any caller can render it as success. */
export function validateExecutionResult(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) return invalid("Execution result must be an object");
const keys = Object.keys(value).sort();
const expected = ["code", "data", "evidence", "schemaVersion", "status", "summary"];
if (JSON.stringify(keys) !== JSON.stringify(expected)) return invalid("Execution result contains missing or unknown fields");
if (value.schemaVersion !== EXECUTION_RESULT_SCHEMA_VERSION) return invalid("Execution result schema version is unsupported");
if (!EXECUTION_RESULT_STATUSES.includes(value.status)) return invalid("Execution result status is unsupported");
if (typeof value.summary !== "string" || value.summary.trim().length === 0) return invalid("Execution result summary is empty");
if (!Array.isArray(value.evidence) || value.evidence.some((item) => typeof item !== "string" || item.trim().length === 0)) {
return invalid("Execution result evidence is malformed");
}
if (value.status === "success") {
if (value.code !== null) return invalid("Successful execution must not carry an error code");
if (value.evidence.length === 0) return invalid("Successful execution requires evidence", EXECUTION_RESULT_ERROR_CODES.EMPTY);
} else if (typeof value.code !== "string" || !/^[A-Z][A-Z0-9_]{2,63}$/.test(value.code)) {
return invalid("Non-success execution requires a stable error code");
}
return Object.freeze({ ...value, evidence: Object.freeze([...value.evidence]) });
}
export function executionResult(input) {
return validateExecutionResult({
schemaVersion: EXECUTION_RESULT_SCHEMA_VERSION,
status: input.status,
code: input.code ?? null,
summary: input.summary,
evidence: input.evidence ?? [],
data: input.data ?? null,
});
}
export function renderExecutionResult(result, options = {}) {
const valid = validateExecutionResult(result);
if (options.json) return `${JSON.stringify(valid, null, 2)}\n`;
const label = valid.status.toUpperCase();
const code = valid.code ? ` [${valid.code}]` : "";
const evidence = valid.evidence.map((item) => `- ${item}`).join("\n");
return `${label}${code}: ${valid.summary}${evidence ? `\nEvidence:\n${evidence}` : ""}\n`;
}
export function assertSuccessfulExecution(result) {
const valid = validateExecutionResult(result);
if (valid.status === "success") return valid;
throw errorWithCode(valid.summary, valid.code);
}
function invalid(message, code = EXECUTION_RESULT_ERROR_CODES.MALFORMED) {
throw errorWithCode(message, code);
}
+1
View File
@@ -15,3 +15,4 @@ export * from "./doctor.js";
export * from "./cleanup.js"; export * from "./cleanup.js";
export * from "./upgrade.js"; export * from "./upgrade.js";
export * from "./install.js"; export * from "./install.js";
export * from "./execution-result.js";
+3
View File
@@ -288,6 +288,9 @@ export const DEFAULT_RUNTIME_BUNDLE = Object.freeze([
entry("node_modules/detect-libc"), entry("node_modules/detect-libc"),
entry("node_modules/semver"), entry("node_modules/semver"),
entry("node_modules/@anthropic-ai/sdk"), entry("node_modules/@anthropic-ai/sdk"),
entry("node_modules/standardwebhooks"),
entry("node_modules/@stablelib/base64"),
entry("node_modules/fast-sha256"),
entry(platformBinary("design/dist/design"), "core", true), entry(platformBinary("design/dist/design"), "core", true),
entry("design/dist/.version", "core"), entry("design/dist/.version", "core"),
entry(platformBinary("make-pdf/dist/pdf"), "core", true), entry(platformBinary("make-pdf/dist/pdf"), "core", true),
+6 -1
View File
@@ -8,7 +8,12 @@ import {
} from '../../runtime/install.js'; } from '../../runtime/install.js';
const ROOT = path.resolve(import.meta.dir, '../..'); const ROOT = path.resolve(import.meta.dir, '../..');
const REQUIRED_CAPABILITIES = ['browse', 'gstack-design', 'make-pdf'] as const; const REQUIRED_CAPABILITIES = [
'browse',
'gstack-design',
'make-pdf',
...(process.platform === 'darwin' ? ['gstack-ios-qa-daemon', 'gstack-ios-qa-mint'] : []),
] as const;
export interface RuntimePayloadEntry { export interface RuntimePayloadEntry {
path: string; path: string;
+77
View File
@@ -0,0 +1,77 @@
import type { ExecutionProfile } from './types';
export interface ExecutionProfileContract {
profile: ExecutionProfile;
inferWhen: string;
mandatoryModules: string;
legalSkips: string;
artifacts: string;
allowedClaims: string;
}
export const EXECUTION_PROFILE_CONTRACTS: Record<ExecutionProfile, ExecutionProfileContract> = {
readiness: {
profile: 'readiness',
inferWhen: 'A narrow, reversible, pre-deployment or operational readiness decision needs bounded evidence; the requested claim is readiness, not completeness.',
mandatoryModules: 'Every selected specialist module remains mandatory. Run its entry gates and the smallest source-authorized evidence path that can answer the readiness question.',
legalSkips: 'Only source-declared conditional work whose condition is demonstrably false, or evidence unavailable after a named attempt. Never skip a STOP gate, approval boundary, reproduction/root-cause gate, or required physical-device/production evidence.',
artifacts: 'A readiness record naming the exact scope, probes run, evidence and freshness, failures, skipped work with reasons, and the next standard/deep step.',
allowedClaims: 'Only ready/not-ready for the named bounded decision. Must say “Readiness profile — not a complete review.” Never claim comprehensive, fully verified, production-safe, or no issues found outside the inspected scope.',
},
standard: {
profile: 'standard',
inferWhen: 'Normal feature or change work has bounded scope and risk and needs the selected specialists complete default workflow.',
mandatoryModules: 'Every selected specialist module and all of its mandatory phases, gates, artifacts, and exit checks.',
legalSkips: 'Only smart skips explicitly authorized by the specialist and supported by inspected evidence; list each skipped primary module and each skipped conditional phase.',
artifacts: 'Every artifact required by the selected specialist, plus evidence provenance, unresolved decisions, and a skip ledger.',
allowedClaims: 'Complete only for the named specialist scope and evidence layer. Broader product, security, production, or device claims require those modules and evidence.',
},
deep: {
profile: 'deep',
inferWhen: 'Risk, ambiguity, blast radius, cross-system effects, irreversible mutation, security/reliability needs, or production deployment demands stronger evidence.',
mandatoryModules: 'Every selected specialist module, all mandatory phases and outside-voice/cross-consumer modules selected by the dispatcher, with unchanged STOP and approval gates.',
legalSkips: 'Only specialist-authorized smart skips proven irrelevant. Missing, stale, malformed, or contradictory evidence is a gap or blocker, never a successful skip.',
artifacts: 'All specialist artifacts plus changed-input/unchanged-consumer trace, negative and failure-path evidence, provenance/freshness, rollback or reversibility evidence where applicable, and unresolved-risk ledger.',
allowedClaims: 'Complete only across the explicitly listed modules and evidence layers. “Confirmed” requires independent supporting evidence; production/device/security claims require matching production/device/security evidence.',
},
};
/** Infer from structured operating conditions, never prompt text. */
export function inferExecutionProfile(
signals: Record<string, unknown>,
specialistDefault: ExecutionProfile,
): ExecutionProfile {
const highRisk = signals.risk === 'high'
|| signals.blast_radius === 'broad'
|| signals.irreversible === true
|| signals.audit_focus === 'security'
|| signals.audit_focus === 'deep'
|| signals.evidence_need === 'independent'
|| signals.failure_impact === 'critical'
|| signals.mutation_scope === 'consequential'
|| signals.external_mutation_authorized === true
|| signals.deployment_state === 'production'
|| signals.release_stage === 'approved-pr'
|| signals.release_stage === 'landed';
if (highRisk) return 'deep';
const boundedReadiness = signals.evidence_need === 'readiness'
&& signals.scope === 'narrow'
&& signals.irreversible !== true
&& signals.mutation_scope !== 'consequential'
&& signals.external_mutation_authorized !== true
&& signals.deployment_state !== 'production'
&& signals.release_stage !== 'approved-pr'
&& signals.release_stage !== 'landed';
if (boundedReadiness) return 'readiness';
return specialistDefault;
}
export function renderExecutionProfiles(): string {
const rows = (['readiness', 'standard', 'deep'] as const).map((name) => {
const contract = EXECUTION_PROFILE_CONTRACTS[name];
return `## ${name === 'readiness' ? 'Smoke/readiness' : name[0].toUpperCase() + name.slice(1)}\n\n- Infer when: ${contract.inferWhen}\n- Mandatory modules: ${contract.mandatoryModules}\n- Legal skips: ${contract.legalSkips}\n- Artifacts: ${contract.artifacts}\n- Claims: ${contract.allowedClaims}`;
});
return `# Inferred execution profiles\n\nChoose a profile from product stage, mutation authority, risk/evidence needs, and deployment state. Prompt keywords and a request to “be quick” are not routing evidence. A profile narrows or strengthens evidence; it never overrides a specialists binding question order, pressure, gates, mutation boundary, or exit behavior.\n\n${rows.join('\n\n')}\n`;
}
+10 -2
View File
@@ -4,6 +4,8 @@ import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import { BUG_FIX_OVERLAYS, overlaysForSource } from './bug-fix-overlays'; import { BUG_FIX_OVERLAYS, overlaysForSource } from './bug-fix-overlays';
import { renderBrowserProviderContract } from './browser-provider-contract'; import { renderBrowserProviderContract } from './browser-provider-contract';
import { EXECUTION_RESULT_SCHEMA } from '../../runtime/execution-result.js';
import { renderExecutionProfiles } from './execution-profiles';
import { contractFor, DISPATCHERS, SOURCE_ASSIGNMENTS } from './assignments'; import { contractFor, DISPATCHERS, SOURCE_ASSIGNMENTS } from './assignments';
import { SCENARIOS } from './scenarios'; import { SCENARIOS } from './scenarios';
import { runDeterministicSemanticParity } from './semantic-parity'; import { runDeterministicSemanticParity } from './semantic-parity';
@@ -220,7 +222,7 @@ Before any substantive output, print these exact labels in this exact order. Res
\`\`\`text \`\`\`text
Target: <concrete repository, product, URL, device, PR, or artifact> Target: <concrete repository, product, URL, device, PR, or artifact>
Mode: <selected top-level mode> Mode: <selected top-level mode>
Depth: <quick, standard, or deep> Depth: <readiness, standard, or deep>
Mutation: <report-only or exact authorized mutation boundary> Mutation: <report-only or exact authorized mutation boundary>
Active modules: <comma-separated internal specialist modules> Active modules: <comma-separated internal specialist modules>
Skipped modules: <comma-separated non-active mandatory modules with compact reasons> Skipped modules: <comma-separated non-active mandatory modules with compact reasons>
@@ -232,7 +234,7 @@ Web context: <none, optional, local-browser, or production>
1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone. 1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone.
2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output. 2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output.
3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference. 3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference.
4. Read \`references/SHARED-JUDGMENT.md\` and \`references/AUTHORITY-POLICY.md\` for every invocation. Read \`references/RUNTIME.md\` before capability-dependent work and \`references/WEB-CONTEXT.md\` before public-web work. 4. Read \`references/EXECUTION-PROFILES.md\`, \`references/SHARED-JUDGMENT.md\`, and \`references/AUTHORITY-POLICY.md\` for every invocation. Infer Depth from structured operating conditions, then obey its mandatory modules, legal skips, artifacts, and claim limits. Read \`references/RUNTIME.md\` before capability-dependent work and \`references/WEB-CONTEXT.md\` before public-web work.
5. If an old asset path is unavailable, use \`references/ASSETS.md\`. If legacy prose invokes another retired skill, resolve it through \`references/COMPATIBILITY.md\` and stay inside these six dispatchers. 5. If an old asset path is unavailable, use \`references/ASSETS.md\`. If legacy prose invokes another retired skill, resolve it through \`references/COMPATIBILITY.md\` and stay inside these six dispatchers.
6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user. 6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user.
7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy. 7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy.
@@ -514,6 +516,10 @@ Some retained helpers are shell scripts. \`gstack doctor\` verifies Bash and, on
The package/runtime compatibility tuple is \`schemaVersion=1\`, \`runtimeVersion=2.0.0\`, and \`skillApi=2.0\`; the machine-readable copy is \`references/support/runtime-contract.json\`. An incompatible active runtime is unavailable, not permission to upgrade it. The package/runtime compatibility tuple is \`schemaVersion=1\`, \`runtimeVersion=2.0.0\`, and \`skillApi=2.0\`; the machine-readable copy is \`references/support/runtime-contract.json\`. An incompatible active runtime is unavailable, not permission to upgrade it.
Every optional-runtime tool result must satisfy \`references/support/execution-result-contract.json\` before it is presented as success. Success requires non-empty evidence. Empty or malformed output and explicit degraded, unsupported, or failed statuses remain non-success with stable codes; human renderings must preserve that status and code.
Use \`gstack doctor --capability browser|design|diagram|pdf|ios\` (optionally \`--json\`) for a non-mutating, capability-specific readiness result. Its independent axes must remain distinct: pure judgment availability, platform support, preview consent, install consent, and runtime readiness. Readiness is exactly \`ready\`, \`degraded\`, \`unavailable\`, \`unsupported\`, or \`failed\`. Doctor never grants or persists consent, previews metadata, or installs anything. \`unavailable\` means setup may be offered; \`failed\` means selected runtime evidence failed; \`unsupported\` is a platform boundary; and \`degraded\` means the capability passed while the managed runtime has a warning.
The developer-only fallback is \`node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes\`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment. The developer-only fallback is \`node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes\`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment.
`; `;
} }
@@ -567,6 +573,7 @@ function writeSharedContracts(): void {
const browserChoice = fs.readFileSync(path.join(ROOT, 'runtime', 'browser-choice.mjs')); const browserChoice = fs.readFileSync(path.join(ROOT, 'runtime', 'browser-choice.mjs'));
const browserSmoke = fs.readFileSync(path.join(ROOT, 'runtime', 'browser-provider-smoke.mjs')); const browserSmoke = fs.readFileSync(path.join(ROOT, 'runtime', 'browser-provider-smoke.mjs'));
for (const tree of TREE_NAMES) { for (const tree of TREE_NAMES) {
write(path.join(ROOT, 'skills', tree, 'references', 'EXECUTION-PROFILES.md'), `${GENERATED}\n${renderExecutionProfiles()}`);
write(path.join(ROOT, 'skills', tree, 'references', 'SHARED-JUDGMENT.md'), sharedJudgmentContract()); write(path.join(ROOT, 'skills', tree, 'references', 'SHARED-JUDGMENT.md'), sharedJudgmentContract());
write(path.join(ROOT, 'skills', tree, 'references', 'AUTHORITY-POLICY.md'), authorityPolicyContract()); write(path.join(ROOT, 'skills', tree, 'references', 'AUTHORITY-POLICY.md'), authorityPolicyContract());
write(path.join(ROOT, 'skills', tree, 'references', 'WEB-CONTEXT.md'), webContextContract()); write(path.join(ROOT, 'skills', tree, 'references', 'WEB-CONTEXT.md'), webContextContract());
@@ -576,6 +583,7 @@ function writeSharedContracts(): void {
write(path.join(ROOT, 'skills', tree, 'references', 'support', 'browser-choice.mjs'), browserChoice); write(path.join(ROOT, 'skills', tree, 'references', 'support', 'browser-choice.mjs'), browserChoice);
write(path.join(ROOT, 'skills', tree, 'references', 'support', 'browser-provider-smoke.mjs'), browserSmoke); write(path.join(ROOT, 'skills', tree, 'references', 'support', 'browser-provider-smoke.mjs'), browserSmoke);
writeJson(path.join(ROOT, 'skills', tree, 'references', 'support', 'runtime-contract.json'), RUNTIME_SKILL_CONTRACT); writeJson(path.join(ROOT, 'skills', tree, 'references', 'support', 'runtime-contract.json'), RUNTIME_SKILL_CONTRACT);
writeJson(path.join(ROOT, 'skills', tree, 'references', 'support', 'execution-result-contract.json'), EXECUTION_RESULT_SCHEMA);
} }
write(path.join(ROOT, 'skills', 'qa', 'references', 'SYSTEM-FUNCTIONAL.md'), systemFunctionalContract()); write(path.join(ROOT, 'skills', 'qa', 'references', 'SYSTEM-FUNCTIONAL.md'), systemFunctionalContract());
write(path.join(ROOT, 'skills', 'ship', 'references', 'EXTERNAL-EFFECTS.md'), externalEffectsContract()); write(path.join(ROOT, 'skills', 'ship', 'references', 'EXTERNAL-EFFECTS.md'), externalEffectsContract());
+3 -3
View File
@@ -116,7 +116,7 @@ export interface StructuredHostResult {
target: string; target: string;
skill: PublicSkill; skill: PublicSkill;
mode: string; mode: string;
depth: 'quick' | 'standard' | 'deep'; depth: 'readiness' | 'standard' | 'deep';
mutation: string; mutation: string;
active_modules: string[]; active_modules: string[];
skipped_modules: string[]; skipped_modules: string[];
@@ -236,7 +236,7 @@ export const FINAL_OUTPUT_SCHEMA = {
target: { type: 'string' }, target: { type: 'string' },
skill: { type: 'string', enum: [...PUBLIC_SKILLS] }, skill: { type: 'string', enum: [...PUBLIC_SKILLS] },
mode: { type: 'string' }, mode: { type: 'string' },
depth: { type: 'string', enum: ['quick', 'standard', 'deep'] }, depth: { type: 'string', enum: ['readiness', 'standard', 'deep'] },
mutation: { type: 'string' }, mutation: { type: 'string' },
active_modules: { type: 'array', items: { type: 'string' } }, active_modules: { type: 'array', items: { type: 'string' } },
skipped_modules: { type: 'array', items: { type: 'string' } }, skipped_modules: { type: 'array', items: { type: 'string' } },
@@ -625,7 +625,7 @@ export function validateStructuredResult(value: unknown): value is StructuredHos
route && typeof route.target === 'string' route && typeof route.target === 'string'
&& PUBLIC_SKILLS.includes(route.skill) && PUBLIC_SKILLS.includes(route.skill)
&& typeof route.mode === 'string' && typeof route.mode === 'string'
&& ['quick', 'standard', 'deep'].includes(route.depth) && ['readiness', 'standard', 'deep'].includes(route.depth)
&& typeof route.mutation === 'string' && typeof route.mutation === 'string'
&& isStringArray(route.active_modules) && isStringArray(route.active_modules)
&& isStringArray(route.skipped_modules) && isStringArray(route.skipped_modules)
+2 -1
View File
@@ -1,6 +1,7 @@
import { DISPATCHERS, SOURCE_ASSIGNMENTS, assignmentBySource } from './assignments'; import { DISPATCHERS, SOURCE_ASSIGNMENTS, assignmentBySource } from './assignments';
import type { ScenarioFixture, TreeName } from './types'; import type { ScenarioFixture, TreeName } from './types';
import { evaluateAuthorityPolicy, type AdversarialAttempt } from './authority-policy'; import { evaluateAuthorityPolicy, type AdversarialAttempt } from './authority-policy';
import { inferExecutionProfile } from './execution-profiles';
export interface StructuredRoute { export interface StructuredRoute {
tree: TreeName; tree: TreeName;
@@ -154,7 +155,7 @@ export function routeStructured(signals: Record<string, unknown>): StructuredRou
return { return {
tree, tree,
mode, mode,
depth: specialist.defaultDepth, depth: inferExecutionProfile(signals, specialist.defaultDepth),
mutation, mutation,
active_modules: active, active_modules: active,
skipped_modules: primary.filter((candidate) => !active.includes(candidate)), skipped_modules: primary.filter((candidate) => !active.includes(candidate)),
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env bun
import { collectFreeTestFiles } from '../test-free-shards';
import { runStrictTestShard } from '../test-free-strict';
const GSTACK2_TEST_TIMEOUT_MS = 30_000;
const files = collectFreeTestFiles().filter((file) => /^test\/gstack2-.*\.test\.ts$/.test(file));
if (files.length === 0) {
throw new Error('No GStack 2 test files were discovered.');
}
console.log(`[test:gstack2] ${files.length} files across ${files.length} isolated processes`);
for (let index = 0; index < files.length; index += 1) {
const file = files[index];
console.log(`[test:gstack2] file ${index + 1}/${files.length}: ${file}`);
const exitCode = await runStrictTestShard([file], GSTACK2_TEST_TIMEOUT_MS);
if (exitCode !== 0) {
process.exitCode = exitCode;
break;
}
}
+4 -3
View File
@@ -2,6 +2,7 @@ export const GSTACK2_BASE_SHA = 'bb57306d98c97011b0919c6132705a15b1579781';
export const TREE_NAMES = ['plan', 'design', 'qa', 'debug', 'review', 'ship'] as const; export const TREE_NAMES = ['plan', 'design', 'qa', 'debug', 'review', 'ship'] as const;
export type TreeName = (typeof TREE_NAMES)[number]; export type TreeName = (typeof TREE_NAMES)[number];
export type ExecutionProfile = 'readiness' | 'standard' | 'deep';
export type ModuleVisibility = 'primary' | 'internal'; export type ModuleVisibility = 'primary' | 'internal';
@@ -27,7 +28,7 @@ export interface SourceAssignment {
mandatory: boolean; mandatory: boolean;
replacement: string; replacement: string;
summary: string; summary: string;
defaultDepth: 'quick' | 'standard' | 'deep'; defaultDepth: ExecutionProfile;
defaultMutation: string; defaultMutation: string;
webContext: 'none' | 'optional' | 'local-browser' | 'production'; webContext: 'none' | 'optional' | 'local-browser' | 'production';
overlays?: number[]; overlays?: number[];
@@ -39,7 +40,7 @@ export interface DispatcherMode {
target: string; target: string;
modules: string[]; modules: string[];
inferWhen: string; inferWhen: string;
depth: 'quick' | 'standard' | 'deep'; depth: ExecutionProfile;
mutation: string; mutation: string;
webContext: 'none' | 'optional' | 'local-browser' | 'production'; webContext: 'none' | 'optional' | 'local-browser' | 'production';
} }
@@ -75,7 +76,7 @@ export interface ScenarioFixture {
expected: { expected: {
tree: TreeName; tree: TreeName;
mode: string; mode: string;
depth: 'quick' | 'standard' | 'deep'; depth: ExecutionProfile;
mutation: string; mutation: string;
active_modules: string[]; active_modules: string[];
skipped_modules: string[]; skipped_modules: string[];
+5 -2
View File
@@ -302,8 +302,11 @@ export function planBoundedFreeTestShards(
return shards; return shards;
} }
export function buildShardArgs(files: string[]): string[] { export function buildShardArgs(files: string[], timeoutMs = FREE_TEST_TIMEOUT_MS): string[] {
return ['test', ...files, '--max-concurrency=1', `--timeout=${FREE_TEST_TIMEOUT_MS}`]; if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {
throw new Error(`Test timeout must be a positive integer. Received: ${timeoutMs}`);
}
return ['test', ...files, '--max-concurrency=1', `--timeout=${timeoutMs}`];
} }
type CliOptions = { type CliOptions = {
+5 -2
View File
@@ -261,9 +261,12 @@ export async function runDefaultFreeTests(): Promise<number> {
return slopSignal === null ? 0 : terminationSignalExitCode(slopSignal); return slopSignal === null ? 0 : terminationSignalExitCode(slopSignal);
} }
export async function runStrictTestShard(files: string[]): Promise<number> { export async function runStrictTestShard(
files: string[],
timeoutMs?: number,
): Promise<number> {
if (files.length === 0) throw new Error('Cannot run an empty free-test shard.'); if (files.length === 0) throw new Error('Cannot run an empty free-test shard.');
const child = spawn(process.execPath, buildShardArgs(exactTestFileSelectors(files)), { const child = spawn(process.execPath, buildShardArgs(exactTestFileSelectors(files), timeoutMs), {
cwd: ROOT, cwd: ROOT,
env: process.env, env: process.env,
stdio: ['inherit', 'pipe', 'pipe'], stdio: ['inherit', 'pipe', 'pipe'],
+2 -2
View File
@@ -15,7 +15,7 @@ Before any substantive output, print these exact labels in this exact order. Res
```text ```text
Target: <concrete repository, product, URL, device, PR, or artifact> Target: <concrete repository, product, URL, device, PR, or artifact>
Mode: <selected top-level mode> Mode: <selected top-level mode>
Depth: <quick, standard, or deep> Depth: <readiness, standard, or deep>
Mutation: <report-only or exact authorized mutation boundary> Mutation: <report-only or exact authorized mutation boundary>
Active modules: <comma-separated internal specialist modules> Active modules: <comma-separated internal specialist modules>
Skipped modules: <comma-separated non-active mandatory modules with compact reasons> Skipped modules: <comma-separated non-active mandatory modules with compact reasons>
@@ -27,7 +27,7 @@ Web context: <none, optional, local-browser, or production>
1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone. 1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone.
2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output. 2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output.
3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference. 3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference.
4. Read `references/SHARED-JUDGMENT.md` and `references/AUTHORITY-POLICY.md` for every invocation. Read `references/RUNTIME.md` before capability-dependent work and `references/WEB-CONTEXT.md` before public-web work. 4. Read `references/EXECUTION-PROFILES.md`, `references/SHARED-JUDGMENT.md`, and `references/AUTHORITY-POLICY.md` for every invocation. Infer Depth from structured operating conditions, then obey its mandatory modules, legal skips, artifacts, and claim limits. Read `references/RUNTIME.md` before capability-dependent work and `references/WEB-CONTEXT.md` before public-web work.
5. If an old asset path is unavailable, use `references/ASSETS.md`. If legacy prose invokes another retired skill, resolve it through `references/COMPATIBILITY.md` and stay inside these six dispatchers. 5. If an old asset path is unavailable, use `references/ASSETS.md`. If legacy prose invokes another retired skill, resolve it through `references/COMPATIBILITY.md` and stay inside these six dispatchers.
6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user. 6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user.
7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy. 7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy.
@@ -0,0 +1,28 @@
<!-- GENERATED by scripts/gstack2/generate-skill-tree.ts; do not edit. -->
# Inferred execution profiles
Choose a profile from product stage, mutation authority, risk/evidence needs, and deployment state. Prompt keywords and a request to “be quick” are not routing evidence. A profile narrows or strengthens evidence; it never overrides a specialists binding question order, pressure, gates, mutation boundary, or exit behavior.
## Smoke/readiness
- Infer when: A narrow, reversible, pre-deployment or operational readiness decision needs bounded evidence; the requested claim is readiness, not completeness.
- Mandatory modules: Every selected specialist module remains mandatory. Run its entry gates and the smallest source-authorized evidence path that can answer the readiness question.
- Legal skips: Only source-declared conditional work whose condition is demonstrably false, or evidence unavailable after a named attempt. Never skip a STOP gate, approval boundary, reproduction/root-cause gate, or required physical-device/production evidence.
- Artifacts: A readiness record naming the exact scope, probes run, evidence and freshness, failures, skipped work with reasons, and the next standard/deep step.
- Claims: Only ready/not-ready for the named bounded decision. Must say “Readiness profile — not a complete review.” Never claim comprehensive, fully verified, production-safe, or no issues found outside the inspected scope.
## Standard
- Infer when: Normal feature or change work has bounded scope and risk and needs the selected specialists complete default workflow.
- Mandatory modules: Every selected specialist module and all of its mandatory phases, gates, artifacts, and exit checks.
- Legal skips: Only smart skips explicitly authorized by the specialist and supported by inspected evidence; list each skipped primary module and each skipped conditional phase.
- Artifacts: Every artifact required by the selected specialist, plus evidence provenance, unresolved decisions, and a skip ledger.
- Claims: Complete only for the named specialist scope and evidence layer. Broader product, security, production, or device claims require those modules and evidence.
## Deep
- Infer when: Risk, ambiguity, blast radius, cross-system effects, irreversible mutation, security/reliability needs, or production deployment demands stronger evidence.
- Mandatory modules: Every selected specialist module, all mandatory phases and outside-voice/cross-consumer modules selected by the dispatcher, with unchanged STOP and approval gates.
- Legal skips: Only specialist-authorized smart skips proven irrelevant. Missing, stale, malformed, or contradictory evidence is a gap or blocker, never a successful skip.
- Artifacts: All specialist artifacts plus changed-input/unchanged-consumer trace, negative and failure-path evidence, provenance/freshness, rollback or reversibility evidence where applicable, and unresolved-risk ledger.
- Claims: Complete only across the explicitly listed modules and evidence layers. “Confirmed” requires independent supporting evidence; production/device/security claims require matching production/device/security evidence.
+4
View File
@@ -23,4 +23,8 @@ Some retained helpers are shell scripts. `gstack doctor` verifies Bash and, on W
The package/runtime compatibility tuple is `schemaVersion=1`, `runtimeVersion=2.0.0`, and `skillApi=2.0`; the machine-readable copy is `references/support/runtime-contract.json`. An incompatible active runtime is unavailable, not permission to upgrade it. The package/runtime compatibility tuple is `schemaVersion=1`, `runtimeVersion=2.0.0`, and `skillApi=2.0`; the machine-readable copy is `references/support/runtime-contract.json`. An incompatible active runtime is unavailable, not permission to upgrade it.
Every optional-runtime tool result must satisfy `references/support/execution-result-contract.json` before it is presented as success. Success requires non-empty evidence. Empty or malformed output and explicit degraded, unsupported, or failed statuses remain non-success with stable codes; human renderings must preserve that status and code.
Use `gstack doctor --capability browser|design|diagram|pdf|ios` (optionally `--json`) for a non-mutating, capability-specific readiness result. Its independent axes must remain distinct: pure judgment availability, platform support, preview consent, install consent, and runtime readiness. Readiness is exactly `ready`, `degraded`, `unavailable`, `unsupported`, or `failed`. Doctor never grants or persists consent, previews metadata, or installs anything. `unavailable` means setup may be offered; `failed` means selected runtime evidence failed; `unsupported` is a platform boundary; and `degraded` means the capability passed while the managed runtime has a warning.
The developer-only fallback is `node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment. The developer-only fallback is `node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment.
@@ -0,0 +1,88 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://gstack.dev/schemas/execution-result-v1.json",
"title": "GStack execution result",
"type": "object",
"additionalProperties": false,
"required": [
"schemaVersion",
"status",
"code",
"summary",
"evidence",
"data"
],
"properties": {
"schemaVersion": {
"const": 1
},
"status": {
"enum": [
"success",
"degraded",
"unsupported",
"failed"
]
},
"code": {
"type": [
"string",
"null"
],
"pattern": "^[A-Z][A-Z0-9_]{2,63}$"
},
"summary": {
"type": "string",
"minLength": 1
},
"evidence": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"data": {}
},
"allOf": [
{
"if": {
"properties": {
"status": {
"const": "success"
}
}
},
"then": {
"properties": {
"code": {
"type": "null"
},
"evidence": {
"minItems": 1
}
}
}
},
{
"if": {
"properties": {
"status": {
"enum": [
"degraded",
"unsupported",
"failed"
]
}
}
},
"then": {
"properties": {
"code": {
"type": "string"
}
}
}
}
]
}
+2 -2
View File
@@ -15,7 +15,7 @@ Before any substantive output, print these exact labels in this exact order. Res
```text ```text
Target: <concrete repository, product, URL, device, PR, or artifact> Target: <concrete repository, product, URL, device, PR, or artifact>
Mode: <selected top-level mode> Mode: <selected top-level mode>
Depth: <quick, standard, or deep> Depth: <readiness, standard, or deep>
Mutation: <report-only or exact authorized mutation boundary> Mutation: <report-only or exact authorized mutation boundary>
Active modules: <comma-separated internal specialist modules> Active modules: <comma-separated internal specialist modules>
Skipped modules: <comma-separated non-active mandatory modules with compact reasons> Skipped modules: <comma-separated non-active mandatory modules with compact reasons>
@@ -27,7 +27,7 @@ Web context: <none, optional, local-browser, or production>
1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone. 1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone.
2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output. 2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output.
3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference. 3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference.
4. Read `references/SHARED-JUDGMENT.md` and `references/AUTHORITY-POLICY.md` for every invocation. Read `references/RUNTIME.md` before capability-dependent work and `references/WEB-CONTEXT.md` before public-web work. 4. Read `references/EXECUTION-PROFILES.md`, `references/SHARED-JUDGMENT.md`, and `references/AUTHORITY-POLICY.md` for every invocation. Infer Depth from structured operating conditions, then obey its mandatory modules, legal skips, artifacts, and claim limits. Read `references/RUNTIME.md` before capability-dependent work and `references/WEB-CONTEXT.md` before public-web work.
5. If an old asset path is unavailable, use `references/ASSETS.md`. If legacy prose invokes another retired skill, resolve it through `references/COMPATIBILITY.md` and stay inside these six dispatchers. 5. If an old asset path is unavailable, use `references/ASSETS.md`. If legacy prose invokes another retired skill, resolve it through `references/COMPATIBILITY.md` and stay inside these six dispatchers.
6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user. 6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user.
7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy. 7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy.
@@ -0,0 +1,28 @@
<!-- GENERATED by scripts/gstack2/generate-skill-tree.ts; do not edit. -->
# Inferred execution profiles
Choose a profile from product stage, mutation authority, risk/evidence needs, and deployment state. Prompt keywords and a request to “be quick” are not routing evidence. A profile narrows or strengthens evidence; it never overrides a specialists binding question order, pressure, gates, mutation boundary, or exit behavior.
## Smoke/readiness
- Infer when: A narrow, reversible, pre-deployment or operational readiness decision needs bounded evidence; the requested claim is readiness, not completeness.
- Mandatory modules: Every selected specialist module remains mandatory. Run its entry gates and the smallest source-authorized evidence path that can answer the readiness question.
- Legal skips: Only source-declared conditional work whose condition is demonstrably false, or evidence unavailable after a named attempt. Never skip a STOP gate, approval boundary, reproduction/root-cause gate, or required physical-device/production evidence.
- Artifacts: A readiness record naming the exact scope, probes run, evidence and freshness, failures, skipped work with reasons, and the next standard/deep step.
- Claims: Only ready/not-ready for the named bounded decision. Must say “Readiness profile — not a complete review.” Never claim comprehensive, fully verified, production-safe, or no issues found outside the inspected scope.
## Standard
- Infer when: Normal feature or change work has bounded scope and risk and needs the selected specialists complete default workflow.
- Mandatory modules: Every selected specialist module and all of its mandatory phases, gates, artifacts, and exit checks.
- Legal skips: Only smart skips explicitly authorized by the specialist and supported by inspected evidence; list each skipped primary module and each skipped conditional phase.
- Artifacts: Every artifact required by the selected specialist, plus evidence provenance, unresolved decisions, and a skip ledger.
- Claims: Complete only for the named specialist scope and evidence layer. Broader product, security, production, or device claims require those modules and evidence.
## Deep
- Infer when: Risk, ambiguity, blast radius, cross-system effects, irreversible mutation, security/reliability needs, or production deployment demands stronger evidence.
- Mandatory modules: Every selected specialist module, all mandatory phases and outside-voice/cross-consumer modules selected by the dispatcher, with unchanged STOP and approval gates.
- Legal skips: Only specialist-authorized smart skips proven irrelevant. Missing, stale, malformed, or contradictory evidence is a gap or blocker, never a successful skip.
- Artifacts: All specialist artifacts plus changed-input/unchanged-consumer trace, negative and failure-path evidence, provenance/freshness, rollback or reversibility evidence where applicable, and unresolved-risk ledger.
- Claims: Complete only across the explicitly listed modules and evidence layers. “Confirmed” requires independent supporting evidence; production/device/security claims require matching production/device/security evidence.
+4
View File
@@ -23,4 +23,8 @@ Some retained helpers are shell scripts. `gstack doctor` verifies Bash and, on W
The package/runtime compatibility tuple is `schemaVersion=1`, `runtimeVersion=2.0.0`, and `skillApi=2.0`; the machine-readable copy is `references/support/runtime-contract.json`. An incompatible active runtime is unavailable, not permission to upgrade it. The package/runtime compatibility tuple is `schemaVersion=1`, `runtimeVersion=2.0.0`, and `skillApi=2.0`; the machine-readable copy is `references/support/runtime-contract.json`. An incompatible active runtime is unavailable, not permission to upgrade it.
Every optional-runtime tool result must satisfy `references/support/execution-result-contract.json` before it is presented as success. Success requires non-empty evidence. Empty or malformed output and explicit degraded, unsupported, or failed statuses remain non-success with stable codes; human renderings must preserve that status and code.
Use `gstack doctor --capability browser|design|diagram|pdf|ios` (optionally `--json`) for a non-mutating, capability-specific readiness result. Its independent axes must remain distinct: pure judgment availability, platform support, preview consent, install consent, and runtime readiness. Readiness is exactly `ready`, `degraded`, `unavailable`, `unsupported`, or `failed`. Doctor never grants or persists consent, previews metadata, or installs anything. `unavailable` means setup may be offered; `failed` means selected runtime evidence failed; `unsupported` is a platform boundary; and `degraded` means the capability passed while the managed runtime has a warning.
The developer-only fallback is `node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment. The developer-only fallback is `node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment.
@@ -0,0 +1,88 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://gstack.dev/schemas/execution-result-v1.json",
"title": "GStack execution result",
"type": "object",
"additionalProperties": false,
"required": [
"schemaVersion",
"status",
"code",
"summary",
"evidence",
"data"
],
"properties": {
"schemaVersion": {
"const": 1
},
"status": {
"enum": [
"success",
"degraded",
"unsupported",
"failed"
]
},
"code": {
"type": [
"string",
"null"
],
"pattern": "^[A-Z][A-Z0-9_]{2,63}$"
},
"summary": {
"type": "string",
"minLength": 1
},
"evidence": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"data": {}
},
"allOf": [
{
"if": {
"properties": {
"status": {
"const": "success"
}
}
},
"then": {
"properties": {
"code": {
"type": "null"
},
"evidence": {
"minItems": 1
}
}
}
},
{
"if": {
"properties": {
"status": {
"enum": [
"degraded",
"unsupported",
"failed"
]
}
}
},
"then": {
"properties": {
"code": {
"type": "string"
}
}
}
}
]
}
+2 -2
View File
@@ -15,7 +15,7 @@ Before any substantive output, print these exact labels in this exact order. Res
```text ```text
Target: <concrete repository, product, URL, device, PR, or artifact> Target: <concrete repository, product, URL, device, PR, or artifact>
Mode: <selected top-level mode> Mode: <selected top-level mode>
Depth: <quick, standard, or deep> Depth: <readiness, standard, or deep>
Mutation: <report-only or exact authorized mutation boundary> Mutation: <report-only or exact authorized mutation boundary>
Active modules: <comma-separated internal specialist modules> Active modules: <comma-separated internal specialist modules>
Skipped modules: <comma-separated non-active mandatory modules with compact reasons> Skipped modules: <comma-separated non-active mandatory modules with compact reasons>
@@ -27,7 +27,7 @@ Web context: <none, optional, local-browser, or production>
1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone. 1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone.
2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output. 2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output.
3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference. 3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference.
4. Read `references/SHARED-JUDGMENT.md` and `references/AUTHORITY-POLICY.md` for every invocation. Read `references/RUNTIME.md` before capability-dependent work and `references/WEB-CONTEXT.md` before public-web work. 4. Read `references/EXECUTION-PROFILES.md`, `references/SHARED-JUDGMENT.md`, and `references/AUTHORITY-POLICY.md` for every invocation. Infer Depth from structured operating conditions, then obey its mandatory modules, legal skips, artifacts, and claim limits. Read `references/RUNTIME.md` before capability-dependent work and `references/WEB-CONTEXT.md` before public-web work.
5. If an old asset path is unavailable, use `references/ASSETS.md`. If legacy prose invokes another retired skill, resolve it through `references/COMPATIBILITY.md` and stay inside these six dispatchers. 5. If an old asset path is unavailable, use `references/ASSETS.md`. If legacy prose invokes another retired skill, resolve it through `references/COMPATIBILITY.md` and stay inside these six dispatchers.
6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user. 6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user.
7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy. 7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy.
@@ -0,0 +1,28 @@
<!-- GENERATED by scripts/gstack2/generate-skill-tree.ts; do not edit. -->
# Inferred execution profiles
Choose a profile from product stage, mutation authority, risk/evidence needs, and deployment state. Prompt keywords and a request to “be quick” are not routing evidence. A profile narrows or strengthens evidence; it never overrides a specialists binding question order, pressure, gates, mutation boundary, or exit behavior.
## Smoke/readiness
- Infer when: A narrow, reversible, pre-deployment or operational readiness decision needs bounded evidence; the requested claim is readiness, not completeness.
- Mandatory modules: Every selected specialist module remains mandatory. Run its entry gates and the smallest source-authorized evidence path that can answer the readiness question.
- Legal skips: Only source-declared conditional work whose condition is demonstrably false, or evidence unavailable after a named attempt. Never skip a STOP gate, approval boundary, reproduction/root-cause gate, or required physical-device/production evidence.
- Artifacts: A readiness record naming the exact scope, probes run, evidence and freshness, failures, skipped work with reasons, and the next standard/deep step.
- Claims: Only ready/not-ready for the named bounded decision. Must say “Readiness profile — not a complete review.” Never claim comprehensive, fully verified, production-safe, or no issues found outside the inspected scope.
## Standard
- Infer when: Normal feature or change work has bounded scope and risk and needs the selected specialists complete default workflow.
- Mandatory modules: Every selected specialist module and all of its mandatory phases, gates, artifacts, and exit checks.
- Legal skips: Only smart skips explicitly authorized by the specialist and supported by inspected evidence; list each skipped primary module and each skipped conditional phase.
- Artifacts: Every artifact required by the selected specialist, plus evidence provenance, unresolved decisions, and a skip ledger.
- Claims: Complete only for the named specialist scope and evidence layer. Broader product, security, production, or device claims require those modules and evidence.
## Deep
- Infer when: Risk, ambiguity, blast radius, cross-system effects, irreversible mutation, security/reliability needs, or production deployment demands stronger evidence.
- Mandatory modules: Every selected specialist module, all mandatory phases and outside-voice/cross-consumer modules selected by the dispatcher, with unchanged STOP and approval gates.
- Legal skips: Only specialist-authorized smart skips proven irrelevant. Missing, stale, malformed, or contradictory evidence is a gap or blocker, never a successful skip.
- Artifacts: All specialist artifacts plus changed-input/unchanged-consumer trace, negative and failure-path evidence, provenance/freshness, rollback or reversibility evidence where applicable, and unresolved-risk ledger.
- Claims: Complete only across the explicitly listed modules and evidence layers. “Confirmed” requires independent supporting evidence; production/device/security claims require matching production/device/security evidence.
+4
View File
@@ -23,4 +23,8 @@ Some retained helpers are shell scripts. `gstack doctor` verifies Bash and, on W
The package/runtime compatibility tuple is `schemaVersion=1`, `runtimeVersion=2.0.0`, and `skillApi=2.0`; the machine-readable copy is `references/support/runtime-contract.json`. An incompatible active runtime is unavailable, not permission to upgrade it. The package/runtime compatibility tuple is `schemaVersion=1`, `runtimeVersion=2.0.0`, and `skillApi=2.0`; the machine-readable copy is `references/support/runtime-contract.json`. An incompatible active runtime is unavailable, not permission to upgrade it.
Every optional-runtime tool result must satisfy `references/support/execution-result-contract.json` before it is presented as success. Success requires non-empty evidence. Empty or malformed output and explicit degraded, unsupported, or failed statuses remain non-success with stable codes; human renderings must preserve that status and code.
Use `gstack doctor --capability browser|design|diagram|pdf|ios` (optionally `--json`) for a non-mutating, capability-specific readiness result. Its independent axes must remain distinct: pure judgment availability, platform support, preview consent, install consent, and runtime readiness. Readiness is exactly `ready`, `degraded`, `unavailable`, `unsupported`, or `failed`. Doctor never grants or persists consent, previews metadata, or installs anything. `unavailable` means setup may be offered; `failed` means selected runtime evidence failed; `unsupported` is a platform boundary; and `degraded` means the capability passed while the managed runtime has a warning.
The developer-only fallback is `node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment. The developer-only fallback is `node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment.
@@ -0,0 +1,88 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://gstack.dev/schemas/execution-result-v1.json",
"title": "GStack execution result",
"type": "object",
"additionalProperties": false,
"required": [
"schemaVersion",
"status",
"code",
"summary",
"evidence",
"data"
],
"properties": {
"schemaVersion": {
"const": 1
},
"status": {
"enum": [
"success",
"degraded",
"unsupported",
"failed"
]
},
"code": {
"type": [
"string",
"null"
],
"pattern": "^[A-Z][A-Z0-9_]{2,63}$"
},
"summary": {
"type": "string",
"minLength": 1
},
"evidence": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"data": {}
},
"allOf": [
{
"if": {
"properties": {
"status": {
"const": "success"
}
}
},
"then": {
"properties": {
"code": {
"type": "null"
},
"evidence": {
"minItems": 1
}
}
}
},
{
"if": {
"properties": {
"status": {
"enum": [
"degraded",
"unsupported",
"failed"
]
}
}
},
"then": {
"properties": {
"code": {
"type": "string"
}
}
}
}
]
}
+2 -2
View File
@@ -15,7 +15,7 @@ Before any substantive output, print these exact labels in this exact order. Res
```text ```text
Target: <concrete repository, product, URL, device, PR, or artifact> Target: <concrete repository, product, URL, device, PR, or artifact>
Mode: <selected top-level mode> Mode: <selected top-level mode>
Depth: <quick, standard, or deep> Depth: <readiness, standard, or deep>
Mutation: <report-only or exact authorized mutation boundary> Mutation: <report-only or exact authorized mutation boundary>
Active modules: <comma-separated internal specialist modules> Active modules: <comma-separated internal specialist modules>
Skipped modules: <comma-separated non-active mandatory modules with compact reasons> Skipped modules: <comma-separated non-active mandatory modules with compact reasons>
@@ -27,7 +27,7 @@ Web context: <none, optional, local-browser, or production>
1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone. 1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone.
2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output. 2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output.
3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference. 3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference.
4. Read `references/SHARED-JUDGMENT.md` and `references/AUTHORITY-POLICY.md` for every invocation. Read `references/RUNTIME.md` before capability-dependent work and `references/WEB-CONTEXT.md` before public-web work. 4. Read `references/EXECUTION-PROFILES.md`, `references/SHARED-JUDGMENT.md`, and `references/AUTHORITY-POLICY.md` for every invocation. Infer Depth from structured operating conditions, then obey its mandatory modules, legal skips, artifacts, and claim limits. Read `references/RUNTIME.md` before capability-dependent work and `references/WEB-CONTEXT.md` before public-web work.
5. If an old asset path is unavailable, use `references/ASSETS.md`. If legacy prose invokes another retired skill, resolve it through `references/COMPATIBILITY.md` and stay inside these six dispatchers. 5. If an old asset path is unavailable, use `references/ASSETS.md`. If legacy prose invokes another retired skill, resolve it through `references/COMPATIBILITY.md` and stay inside these six dispatchers.
6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user. 6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user.
7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy. 7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy.
@@ -0,0 +1,28 @@
<!-- GENERATED by scripts/gstack2/generate-skill-tree.ts; do not edit. -->
# Inferred execution profiles
Choose a profile from product stage, mutation authority, risk/evidence needs, and deployment state. Prompt keywords and a request to “be quick” are not routing evidence. A profile narrows or strengthens evidence; it never overrides a specialists binding question order, pressure, gates, mutation boundary, or exit behavior.
## Smoke/readiness
- Infer when: A narrow, reversible, pre-deployment or operational readiness decision needs bounded evidence; the requested claim is readiness, not completeness.
- Mandatory modules: Every selected specialist module remains mandatory. Run its entry gates and the smallest source-authorized evidence path that can answer the readiness question.
- Legal skips: Only source-declared conditional work whose condition is demonstrably false, or evidence unavailable after a named attempt. Never skip a STOP gate, approval boundary, reproduction/root-cause gate, or required physical-device/production evidence.
- Artifacts: A readiness record naming the exact scope, probes run, evidence and freshness, failures, skipped work with reasons, and the next standard/deep step.
- Claims: Only ready/not-ready for the named bounded decision. Must say “Readiness profile — not a complete review.” Never claim comprehensive, fully verified, production-safe, or no issues found outside the inspected scope.
## Standard
- Infer when: Normal feature or change work has bounded scope and risk and needs the selected specialists complete default workflow.
- Mandatory modules: Every selected specialist module and all of its mandatory phases, gates, artifacts, and exit checks.
- Legal skips: Only smart skips explicitly authorized by the specialist and supported by inspected evidence; list each skipped primary module and each skipped conditional phase.
- Artifacts: Every artifact required by the selected specialist, plus evidence provenance, unresolved decisions, and a skip ledger.
- Claims: Complete only for the named specialist scope and evidence layer. Broader product, security, production, or device claims require those modules and evidence.
## Deep
- Infer when: Risk, ambiguity, blast radius, cross-system effects, irreversible mutation, security/reliability needs, or production deployment demands stronger evidence.
- Mandatory modules: Every selected specialist module, all mandatory phases and outside-voice/cross-consumer modules selected by the dispatcher, with unchanged STOP and approval gates.
- Legal skips: Only specialist-authorized smart skips proven irrelevant. Missing, stale, malformed, or contradictory evidence is a gap or blocker, never a successful skip.
- Artifacts: All specialist artifacts plus changed-input/unchanged-consumer trace, negative and failure-path evidence, provenance/freshness, rollback or reversibility evidence where applicable, and unresolved-risk ledger.
- Claims: Complete only across the explicitly listed modules and evidence layers. “Confirmed” requires independent supporting evidence; production/device/security claims require matching production/device/security evidence.
+4
View File
@@ -23,4 +23,8 @@ Some retained helpers are shell scripts. `gstack doctor` verifies Bash and, on W
The package/runtime compatibility tuple is `schemaVersion=1`, `runtimeVersion=2.0.0`, and `skillApi=2.0`; the machine-readable copy is `references/support/runtime-contract.json`. An incompatible active runtime is unavailable, not permission to upgrade it. The package/runtime compatibility tuple is `schemaVersion=1`, `runtimeVersion=2.0.0`, and `skillApi=2.0`; the machine-readable copy is `references/support/runtime-contract.json`. An incompatible active runtime is unavailable, not permission to upgrade it.
Every optional-runtime tool result must satisfy `references/support/execution-result-contract.json` before it is presented as success. Success requires non-empty evidence. Empty or malformed output and explicit degraded, unsupported, or failed statuses remain non-success with stable codes; human renderings must preserve that status and code.
Use `gstack doctor --capability browser|design|diagram|pdf|ios` (optionally `--json`) for a non-mutating, capability-specific readiness result. Its independent axes must remain distinct: pure judgment availability, platform support, preview consent, install consent, and runtime readiness. Readiness is exactly `ready`, `degraded`, `unavailable`, `unsupported`, or `failed`. Doctor never grants or persists consent, previews metadata, or installs anything. `unavailable` means setup may be offered; `failed` means selected runtime evidence failed; `unsupported` is a platform boundary; and `degraded` means the capability passed while the managed runtime has a warning.
The developer-only fallback is `node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment. The developer-only fallback is `node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment.
@@ -0,0 +1,88 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://gstack.dev/schemas/execution-result-v1.json",
"title": "GStack execution result",
"type": "object",
"additionalProperties": false,
"required": [
"schemaVersion",
"status",
"code",
"summary",
"evidence",
"data"
],
"properties": {
"schemaVersion": {
"const": 1
},
"status": {
"enum": [
"success",
"degraded",
"unsupported",
"failed"
]
},
"code": {
"type": [
"string",
"null"
],
"pattern": "^[A-Z][A-Z0-9_]{2,63}$"
},
"summary": {
"type": "string",
"minLength": 1
},
"evidence": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"data": {}
},
"allOf": [
{
"if": {
"properties": {
"status": {
"const": "success"
}
}
},
"then": {
"properties": {
"code": {
"type": "null"
},
"evidence": {
"minItems": 1
}
}
}
},
{
"if": {
"properties": {
"status": {
"enum": [
"degraded",
"unsupported",
"failed"
]
}
}
},
"then": {
"properties": {
"code": {
"type": "string"
}
}
}
}
]
}
+2 -2
View File
@@ -15,7 +15,7 @@ Before any substantive output, print these exact labels in this exact order. Res
```text ```text
Target: <concrete repository, product, URL, device, PR, or artifact> Target: <concrete repository, product, URL, device, PR, or artifact>
Mode: <selected top-level mode> Mode: <selected top-level mode>
Depth: <quick, standard, or deep> Depth: <readiness, standard, or deep>
Mutation: <report-only or exact authorized mutation boundary> Mutation: <report-only or exact authorized mutation boundary>
Active modules: <comma-separated internal specialist modules> Active modules: <comma-separated internal specialist modules>
Skipped modules: <comma-separated non-active mandatory modules with compact reasons> Skipped modules: <comma-separated non-active mandatory modules with compact reasons>
@@ -27,7 +27,7 @@ Web context: <none, optional, local-browser, or production>
1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone. 1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone.
2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output. 2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output.
3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference. 3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference.
4. Read `references/SHARED-JUDGMENT.md` and `references/AUTHORITY-POLICY.md` for every invocation. Read `references/RUNTIME.md` before capability-dependent work and `references/WEB-CONTEXT.md` before public-web work. 4. Read `references/EXECUTION-PROFILES.md`, `references/SHARED-JUDGMENT.md`, and `references/AUTHORITY-POLICY.md` for every invocation. Infer Depth from structured operating conditions, then obey its mandatory modules, legal skips, artifacts, and claim limits. Read `references/RUNTIME.md` before capability-dependent work and `references/WEB-CONTEXT.md` before public-web work.
5. If an old asset path is unavailable, use `references/ASSETS.md`. If legacy prose invokes another retired skill, resolve it through `references/COMPATIBILITY.md` and stay inside these six dispatchers. 5. If an old asset path is unavailable, use `references/ASSETS.md`. If legacy prose invokes another retired skill, resolve it through `references/COMPATIBILITY.md` and stay inside these six dispatchers.
6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user. 6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user.
7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy. 7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy.
@@ -0,0 +1,28 @@
<!-- GENERATED by scripts/gstack2/generate-skill-tree.ts; do not edit. -->
# Inferred execution profiles
Choose a profile from product stage, mutation authority, risk/evidence needs, and deployment state. Prompt keywords and a request to “be quick” are not routing evidence. A profile narrows or strengthens evidence; it never overrides a specialists binding question order, pressure, gates, mutation boundary, or exit behavior.
## Smoke/readiness
- Infer when: A narrow, reversible, pre-deployment or operational readiness decision needs bounded evidence; the requested claim is readiness, not completeness.
- Mandatory modules: Every selected specialist module remains mandatory. Run its entry gates and the smallest source-authorized evidence path that can answer the readiness question.
- Legal skips: Only source-declared conditional work whose condition is demonstrably false, or evidence unavailable after a named attempt. Never skip a STOP gate, approval boundary, reproduction/root-cause gate, or required physical-device/production evidence.
- Artifacts: A readiness record naming the exact scope, probes run, evidence and freshness, failures, skipped work with reasons, and the next standard/deep step.
- Claims: Only ready/not-ready for the named bounded decision. Must say “Readiness profile — not a complete review.” Never claim comprehensive, fully verified, production-safe, or no issues found outside the inspected scope.
## Standard
- Infer when: Normal feature or change work has bounded scope and risk and needs the selected specialists complete default workflow.
- Mandatory modules: Every selected specialist module and all of its mandatory phases, gates, artifacts, and exit checks.
- Legal skips: Only smart skips explicitly authorized by the specialist and supported by inspected evidence; list each skipped primary module and each skipped conditional phase.
- Artifacts: Every artifact required by the selected specialist, plus evidence provenance, unresolved decisions, and a skip ledger.
- Claims: Complete only for the named specialist scope and evidence layer. Broader product, security, production, or device claims require those modules and evidence.
## Deep
- Infer when: Risk, ambiguity, blast radius, cross-system effects, irreversible mutation, security/reliability needs, or production deployment demands stronger evidence.
- Mandatory modules: Every selected specialist module, all mandatory phases and outside-voice/cross-consumer modules selected by the dispatcher, with unchanged STOP and approval gates.
- Legal skips: Only specialist-authorized smart skips proven irrelevant. Missing, stale, malformed, or contradictory evidence is a gap or blocker, never a successful skip.
- Artifacts: All specialist artifacts plus changed-input/unchanged-consumer trace, negative and failure-path evidence, provenance/freshness, rollback or reversibility evidence where applicable, and unresolved-risk ledger.
- Claims: Complete only across the explicitly listed modules and evidence layers. “Confirmed” requires independent supporting evidence; production/device/security claims require matching production/device/security evidence.
+4
View File
@@ -23,4 +23,8 @@ Some retained helpers are shell scripts. `gstack doctor` verifies Bash and, on W
The package/runtime compatibility tuple is `schemaVersion=1`, `runtimeVersion=2.0.0`, and `skillApi=2.0`; the machine-readable copy is `references/support/runtime-contract.json`. An incompatible active runtime is unavailable, not permission to upgrade it. The package/runtime compatibility tuple is `schemaVersion=1`, `runtimeVersion=2.0.0`, and `skillApi=2.0`; the machine-readable copy is `references/support/runtime-contract.json`. An incompatible active runtime is unavailable, not permission to upgrade it.
Every optional-runtime tool result must satisfy `references/support/execution-result-contract.json` before it is presented as success. Success requires non-empty evidence. Empty or malformed output and explicit degraded, unsupported, or failed statuses remain non-success with stable codes; human renderings must preserve that status and code.
Use `gstack doctor --capability browser|design|diagram|pdf|ios` (optionally `--json`) for a non-mutating, capability-specific readiness result. Its independent axes must remain distinct: pure judgment availability, platform support, preview consent, install consent, and runtime readiness. Readiness is exactly `ready`, `degraded`, `unavailable`, `unsupported`, or `failed`. Doctor never grants or persists consent, previews metadata, or installs anything. `unavailable` means setup may be offered; `failed` means selected runtime evidence failed; `unsupported` is a platform boundary; and `degraded` means the capability passed while the managed runtime has a warning.
The developer-only fallback is `node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment. The developer-only fallback is `node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment.
@@ -0,0 +1,88 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://gstack.dev/schemas/execution-result-v1.json",
"title": "GStack execution result",
"type": "object",
"additionalProperties": false,
"required": [
"schemaVersion",
"status",
"code",
"summary",
"evidence",
"data"
],
"properties": {
"schemaVersion": {
"const": 1
},
"status": {
"enum": [
"success",
"degraded",
"unsupported",
"failed"
]
},
"code": {
"type": [
"string",
"null"
],
"pattern": "^[A-Z][A-Z0-9_]{2,63}$"
},
"summary": {
"type": "string",
"minLength": 1
},
"evidence": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"data": {}
},
"allOf": [
{
"if": {
"properties": {
"status": {
"const": "success"
}
}
},
"then": {
"properties": {
"code": {
"type": "null"
},
"evidence": {
"minItems": 1
}
}
}
},
{
"if": {
"properties": {
"status": {
"enum": [
"degraded",
"unsupported",
"failed"
]
}
}
},
"then": {
"properties": {
"code": {
"type": "string"
}
}
}
}
]
}
+2 -2
View File
@@ -15,7 +15,7 @@ Before any substantive output, print these exact labels in this exact order. Res
```text ```text
Target: <concrete repository, product, URL, device, PR, or artifact> Target: <concrete repository, product, URL, device, PR, or artifact>
Mode: <selected top-level mode> Mode: <selected top-level mode>
Depth: <quick, standard, or deep> Depth: <readiness, standard, or deep>
Mutation: <report-only or exact authorized mutation boundary> Mutation: <report-only or exact authorized mutation boundary>
Active modules: <comma-separated internal specialist modules> Active modules: <comma-separated internal specialist modules>
Skipped modules: <comma-separated non-active mandatory modules with compact reasons> Skipped modules: <comma-separated non-active mandatory modules with compact reasons>
@@ -27,7 +27,7 @@ Web context: <none, optional, local-browser, or production>
1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone. 1. Infer the mode from product stage, surface, requested artifact, mutation authorization, evidence needs, and deployment state. Do not route by keyword alone.
2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output. 2. Refine the public mode to the smallest applicable internal specialist set, then print the required execution header before any substantive output.
3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference. 3. Read each active module in full from the path shown in the mode/alias tables. Its specialist body, behavioral contract, STOP gates, and appended upstream judgment ports are binding. Read a lazy specialist phase in full only when the workflow reaches its package-local reference.
4. Read `references/SHARED-JUDGMENT.md` and `references/AUTHORITY-POLICY.md` for every invocation. Read `references/RUNTIME.md` before capability-dependent work and `references/WEB-CONTEXT.md` before public-web work. 4. Read `references/EXECUTION-PROFILES.md`, `references/SHARED-JUDGMENT.md`, and `references/AUTHORITY-POLICY.md` for every invocation. Infer Depth from structured operating conditions, then obey its mandatory modules, legal skips, artifacts, and claim limits. Read `references/RUNTIME.md` before capability-dependent work and `references/WEB-CONTEXT.md` before public-web work.
5. If an old asset path is unavailable, use `references/ASSETS.md`. If legacy prose invokes another retired skill, resolve it through `references/COMPATIBILITY.md` and stay inside these six dispatchers. 5. If an old asset path is unavailable, use `references/ASSETS.md`. If legacy prose invokes another retired skill, resolve it through `references/COMPATIBILITY.md` and stay inside these six dispatchers.
6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user. 6. Preserve report-only versus mutation boundaries. Missing mutation authorization fails closed: do not edit merely because a specialist can fix. Commits, pushes, PRs, merges, deploys, messages, and other external mutations still require affirmative authority from the user.
7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy. 7. Match the user's language. Keep code identifiers, commands, and source quotations original when translation would reduce accuracy.
@@ -0,0 +1,28 @@
<!-- GENERATED by scripts/gstack2/generate-skill-tree.ts; do not edit. -->
# Inferred execution profiles
Choose a profile from product stage, mutation authority, risk/evidence needs, and deployment state. Prompt keywords and a request to “be quick” are not routing evidence. A profile narrows or strengthens evidence; it never overrides a specialists binding question order, pressure, gates, mutation boundary, or exit behavior.
## Smoke/readiness
- Infer when: A narrow, reversible, pre-deployment or operational readiness decision needs bounded evidence; the requested claim is readiness, not completeness.
- Mandatory modules: Every selected specialist module remains mandatory. Run its entry gates and the smallest source-authorized evidence path that can answer the readiness question.
- Legal skips: Only source-declared conditional work whose condition is demonstrably false, or evidence unavailable after a named attempt. Never skip a STOP gate, approval boundary, reproduction/root-cause gate, or required physical-device/production evidence.
- Artifacts: A readiness record naming the exact scope, probes run, evidence and freshness, failures, skipped work with reasons, and the next standard/deep step.
- Claims: Only ready/not-ready for the named bounded decision. Must say “Readiness profile — not a complete review.” Never claim comprehensive, fully verified, production-safe, or no issues found outside the inspected scope.
## Standard
- Infer when: Normal feature or change work has bounded scope and risk and needs the selected specialists complete default workflow.
- Mandatory modules: Every selected specialist module and all of its mandatory phases, gates, artifacts, and exit checks.
- Legal skips: Only smart skips explicitly authorized by the specialist and supported by inspected evidence; list each skipped primary module and each skipped conditional phase.
- Artifacts: Every artifact required by the selected specialist, plus evidence provenance, unresolved decisions, and a skip ledger.
- Claims: Complete only for the named specialist scope and evidence layer. Broader product, security, production, or device claims require those modules and evidence.
## Deep
- Infer when: Risk, ambiguity, blast radius, cross-system effects, irreversible mutation, security/reliability needs, or production deployment demands stronger evidence.
- Mandatory modules: Every selected specialist module, all mandatory phases and outside-voice/cross-consumer modules selected by the dispatcher, with unchanged STOP and approval gates.
- Legal skips: Only specialist-authorized smart skips proven irrelevant. Missing, stale, malformed, or contradictory evidence is a gap or blocker, never a successful skip.
- Artifacts: All specialist artifacts plus changed-input/unchanged-consumer trace, negative and failure-path evidence, provenance/freshness, rollback or reversibility evidence where applicable, and unresolved-risk ledger.
- Claims: Complete only across the explicitly listed modules and evidence layers. “Confirmed” requires independent supporting evidence; production/device/security claims require matching production/device/security evidence.
+4
View File
@@ -23,4 +23,8 @@ Some retained helpers are shell scripts. `gstack doctor` verifies Bash and, on W
The package/runtime compatibility tuple is `schemaVersion=1`, `runtimeVersion=2.0.0`, and `skillApi=2.0`; the machine-readable copy is `references/support/runtime-contract.json`. An incompatible active runtime is unavailable, not permission to upgrade it. The package/runtime compatibility tuple is `schemaVersion=1`, `runtimeVersion=2.0.0`, and `skillApi=2.0`; the machine-readable copy is `references/support/runtime-contract.json`. An incompatible active runtime is unavailable, not permission to upgrade it.
Every optional-runtime tool result must satisfy `references/support/execution-result-contract.json` before it is presented as success. Success requires non-empty evidence. Empty or malformed output and explicit degraded, unsupported, or failed statuses remain non-success with stable codes; human renderings must preserve that status and code.
Use `gstack doctor --capability browser|design|diagram|pdf|ios` (optionally `--json`) for a non-mutating, capability-specific readiness result. Its independent axes must remain distinct: pure judgment availability, platform support, preview consent, install consent, and runtime readiness. Readiness is exactly `ready`, `degraded`, `unavailable`, `unsupported`, or `failed`. Doctor never grants or persists consent, previews metadata, or installs anything. `unavailable` means setup may be offered; `failed` means selected runtime evidence failed; `unsupported` is a platform boundary; and `degraded` means the capability passed while the managed runtime has a warning.
The developer-only fallback is `node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment. The developer-only fallback is `node references/support/runtime-bootstrap.mjs install --source <reviewed-checkout> --capability <name> [matching browser flags] --yes`; show its trust warning and use it only when the user explicitly selects a checkout they reviewed. If the packaged bootstrap is unavailable, stop capability setup instead of guessing a checkout-relative command. Deferring installation records no consent and must not block pure judgment.
@@ -0,0 +1,88 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://gstack.dev/schemas/execution-result-v1.json",
"title": "GStack execution result",
"type": "object",
"additionalProperties": false,
"required": [
"schemaVersion",
"status",
"code",
"summary",
"evidence",
"data"
],
"properties": {
"schemaVersion": {
"const": 1
},
"status": {
"enum": [
"success",
"degraded",
"unsupported",
"failed"
]
},
"code": {
"type": [
"string",
"null"
],
"pattern": "^[A-Z][A-Z0-9_]{2,63}$"
},
"summary": {
"type": "string",
"minLength": 1
},
"evidence": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"data": {}
},
"allOf": [
{
"if": {
"properties": {
"status": {
"const": "success"
}
}
},
"then": {
"properties": {
"code": {
"type": "null"
},
"evidence": {
"minItems": 1
}
}
}
},
{
"if": {
"properties": {
"status": {
"enum": [
"degraded",
"unsupported",
"failed"
]
}
}
},
"then": {
"properties": {
"code": {
"type": "string"
}
}
}
}
]
}
+125
View File
@@ -0,0 +1,125 @@
import { describe, expect, test } from "bun:test";
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { main } from "../runtime/cli.js";
import { capabilityReadiness, formatCapabilityReadiness } from "../runtime/doctor.js";
import { setupRuntime } from "../runtime/setup.js";
function report(checks: Array<Record<string, unknown>>) {
return {
ok: !checks.some((check) => check.status === "fail"),
home: "/fixture/.gstack",
checkedAt: "2026-07-20T00:00:00.000Z",
checks,
};
}
function capture() {
let value = "";
return { stream: { write: (chunk: string) => { value += chunk; } }, value: () => value };
}
describe("capability readiness", () => {
test("keeps pure judgment, preview consent, and install consent separate when unavailable", () => {
const result = capabilityReadiness(report([
{ id: "managed-runtime", status: "fail", message: "No active managed runtime" },
{ id: "capability:pdf", status: "warn", message: "not installed" },
]), "pdf");
expect(result).toMatchObject({
ok: false,
judgment: { status: "available" },
platform: { status: "supported" },
consent: {
preview: { status: "required", granted: false },
install: { status: "required-after-preview", granted: false },
},
readiness: { status: "unavailable" },
});
});
test("distinguishes ready, degraded, and failed runtime states", () => {
const ready = capabilityReadiness(report([
{ id: "managed-runtime", status: "pass", message: "active" },
{ id: "capability:design", status: "pass", message: "runnable" },
]), "design");
const degraded = capabilityReadiness(report([
{ id: "managed-runtime", status: "warn", message: "recovered" },
{ id: "capability:design", status: "pass", message: "runnable" },
]), "design");
const failed = capabilityReadiness(report([
{ id: "managed-runtime", status: "pass", message: "active" },
{ id: "capability:diagram", status: "fail", message: "launcher metadata missing" },
]), "diagram");
// A hard runtime failure under a launchable capability is not a warning:
// it must not report ok:true, matching plain `gstack doctor`'s exit code.
const runtimeFailed = capabilityReadiness(report([
{ id: "managed-runtime", status: "fail", message: "incompatible skill API" },
{ id: "capability:browser", status: "pass", message: "launched" },
]), "browser");
expect(ready).toMatchObject({ ok: true, readiness: { status: "ready" } });
expect(degraded).toMatchObject({ ok: true, readiness: { status: "degraded" } });
expect(failed).toMatchObject({ ok: false, readiness: { status: "failed" } });
expect(failed.consent.install.status).toBe("required-after-preview");
expect(runtimeFailed).toMatchObject({ ok: false, readiness: { status: "failed" } });
});
test("reports physical iOS as unsupported without turning off pure judgment", () => {
const result = capabilityReadiness(report([]), "ios", { platform: "linux" });
expect(result).toMatchObject({
ok: false,
judgment: { status: "available" },
platform: { status: "unsupported", platform: "linux" },
consent: {
preview: { status: "not-applicable" },
install: { status: "not-applicable" },
},
readiness: { status: "unsupported" },
});
});
test("human output exposes every state axis", () => {
const result = capabilityReadiness(report([
{ id: "managed-runtime", status: "pass", message: "active" },
{ id: "capability:browser", status: "pass", message: "launched" },
]), "browser");
expect(formatCapabilityReadiness(result)).toContain("judgment: available");
expect(formatCapabilityReadiness(result)).toContain("preview consent: not-required");
expect(formatCapabilityReadiness(result)).toContain("install consent: not-required");
expect(formatCapabilityReadiness(result)).toContain("readiness: ready");
});
test("doctor capability JSON is non-mutating and uses the unified result envelope", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "gstack-capability-doctor-"));
const home = path.join(root, "home");
const stdout = capture();
const stderr = capture();
try {
await setupRuntime({ home, cwd: root });
const exit = await main(["doctor", "--capability", "pdf", "--json"], {
cwd: root,
env: { ...process.env, GSTACK_HOME: home },
stdout: stdout.stream,
stderr: stderr.stream,
});
const result = JSON.parse(stdout.value());
expect(exit).toBe(1);
expect(stderr.value()).toBe("");
expect(result).toMatchObject({
schemaVersion: 1,
status: "degraded",
code: "CAPABILITY_UNAVAILABLE",
data: {
ok: false,
capability: "pdf",
judgment: { status: "available" },
readiness: { status: "unavailable" },
},
});
} finally {
await fs.rm(root, { recursive: true, force: true });
}
});
});
+41
View File
@@ -95,4 +95,45 @@ describe('gstack state external-effect CLI', () => {
{ cwd, env, stdout: out, stderr: err }, { cwd, env, stdout: out, stderr: err },
)).toBe(2); )).toBe(2);
}); });
test('an empty exit-zero tool result is uncertain, never successful', async () => {
const { cwd, env } = await fixture();
const out = sink();
const err = sink();
await main(['state', 'begin', 'ship', '--run-id', 'run_empty'], { cwd, env, stdout: out, stderr: err });
const silent = path.join(cwd, 'silent.sh');
await fs.writeFile(silent, '#!/bin/sh\nexit 0\n', { mode: 0o755 });
const code = await main([
'state', 'effect', 'run_empty', 'silent.tool', '--', silent,
], { cwd, env, stdout: out, stderr: err });
expect(code).toBe(1);
expect(JSON.parse(err.value())).toMatchObject({
status: 'degraded',
code: 'EXECUTION_EMPTY',
evidence: ['exit code 0', 'stdout and stderr were empty'],
});
expect(out.value()).not.toContain('"status":"success"');
const retryError = sink();
expect(await main([
'state', 'effect', 'run_empty', 'silent.tool', '--', silent,
], { cwd, env, stdout: out, stderr: retryError })).toBe(1);
expect(retryError.value()).toContain('was already claimed');
});
test('a nonzero command returns a structured failed result', async () => {
const { cwd, env } = await fixture();
const out = sink();
const err = sink();
await main(['state', 'begin', 'ship', '--run-id', 'run_failed'], { cwd, env, stdout: out, stderr: err });
const code = await main([
'state', 'effect', 'run_failed', 'failed.tool', '--', process.execPath, '-e', 'process.exit(7)',
], { cwd, env, stdout: out, stderr: err });
expect(code).toBe(1);
expect(JSON.parse(err.value())).toMatchObject({
status: 'failed',
code: 'EXECUTION_FAILED',
evidence: ['exit code 7'],
data: { exitCode: 7 },
});
});
}); });
@@ -0,0 +1,35 @@
import { describe, expect, test } from "bun:test";
import {
EXECUTION_RESULT_ERROR_CODES,
executionResult,
renderExecutionResult,
validateExecutionResult,
} from "../runtime/execution-result.js";
describe("GStack execution-result contract", () => {
test("accepts evidenced success and preserves it in both renderings", () => {
const result = executionResult({ status: "success", summary: "Probe completed", evidence: ["exit code 0"], data: { count: 1 } });
expect(JSON.parse(renderExecutionResult(result, { json: true }))).toEqual(result);
expect(renderExecutionResult(result)).toContain("SUCCESS: Probe completed");
});
test("rejects empty and malformed values instead of inferring success", () => {
expect(() => validateExecutionResult(null)).toThrow();
expect(() => executionResult({ status: "success", summary: "Done", evidence: [], data: null }))
.toThrow("requires evidence");
try {
executionResult({ status: "success", summary: "Done", evidence: [], data: null });
} catch (error: any) {
expect(error.code).toBe(EXECUTION_RESULT_ERROR_CODES.EMPTY);
}
});
test.each([
["degraded", "EXECUTION_DEGRADED"],
["unsupported", "EXECUTION_UNSUPPORTED"],
["failed", "EXECUTION_FAILED"],
])("keeps %s explicitly non-success", (status, code) => {
const result = executionResult({ status, code, summary: `${status} result`, evidence: [], data: null });
expect(renderExecutionResult(result)).toStartWith(`${status.toUpperCase()} [${code}]`);
});
});
+3
View File
@@ -630,6 +630,9 @@ process.stdout.write(process.env.GSTACK_CHROMIUM_PATH || "unset");
"node_modules/sharp", "node_modules/sharp",
"node_modules/detect-libc", "node_modules/detect-libc",
"node_modules/semver", "node_modules/semver",
"node_modules/standardwebhooks",
"node_modules/@stablelib/base64",
"node_modules/fast-sha256",
...runtimeNativePackagePaths(), ...runtimeNativePackagePaths(),
]) expect(bundlePaths.has(dependency)).toBe(true); ]) expect(bundlePaths.has(dependency)).toBe(true);
expect(bundlePaths.has("node_modules/@img")).toBe(false); expect(bundlePaths.has("node_modules/@img")).toBe(false);
+3 -1
View File
@@ -45,7 +45,9 @@ describe('GStack 2 generated runtime payload prerequisites', () => {
expect(result.built).toBe(true); expect(result.built).toBe(true);
expect(calls).toHaveLength(1); expect(calls).toHaveLength(1);
expect(calls[0].map((entry) => entry.path)).toEqual(REQUIRED_RUNTIME_PAYLOADS.map((entry) => entry.path)); expect(calls[0].map((entry) => entry.path)).toEqual(REQUIRED_RUNTIME_PAYLOADS.map((entry) => entry.path));
expect(new Set(calls[0].map((entry) => entry.build))).toEqual(new Set(['core'])); expect(new Set(calls[0].map((entry) => entry.build))).toEqual(
new Set(process.platform === 'darwin' ? ['core', 'ios'] : ['core']),
);
}); });
test('does not rebuild payloads that already exist', async () => { test('does not rebuild payloads that already exist', async () => {
+1 -1
View File
@@ -18,7 +18,7 @@ describe('GStack 2 semantic parity', () => {
expect(result.sections).toBe(16); expect(result.sections).toBe(16);
expect(result.policyUnits).toBe(AUTHORITY_POLICY_CASES.length); expect(result.policyUnits).toBe(AUTHORITY_POLICY_CASES.length);
expect(result.checks).toBeGreaterThan(250); expect(result.checks).toBeGreaterThan(250);
}); }, 15_000);
test('authority-policy units cover evidence, trust, and routing controls', () => { test('authority-policy units cover evidence, trust, and routing controls', () => {
expect(AUTHORITY_POLICY_CASES.length).toBeGreaterThanOrEqual(9); expect(AUTHORITY_POLICY_CASES.length).toBeGreaterThanOrEqual(9);
+18
View File
@@ -45,6 +45,21 @@ describe('GStack 2 canonical skill UX', () => {
} }
}); });
test('packages one binding inferred execution-profile contract in every dispatcher', () => {
for (const tree of TREE_NAMES) {
const dispatcher = fs.readFileSync(path.join(ROOT, 'skills', tree, 'SKILL.md'), 'utf8');
const profiles = fs.readFileSync(path.join(ROOT, 'skills', tree, 'references', 'EXECUTION-PROFILES.md'), 'utf8');
expect(dispatcher, tree).toContain('Depth: <readiness, standard, or deep>');
expect(dispatcher, tree).toContain('Read `references/EXECUTION-PROFILES.md`');
expect(profiles, tree).toContain('## Smoke/readiness');
expect(profiles, tree).toContain('Readiness profile — not a complete review.');
expect(profiles, tree).toContain('Every selected specialist module remains mandatory.');
expect(profiles, tree).toContain('## Standard');
expect(profiles, tree).toContain('## Deep');
expect(profiles, tree).toContain('never overrides a specialists binding question order');
}
});
test('resolves retired user-facing recommendations without rewriting package paths', () => { test('resolves retired user-facing recommendations without rewriting package paths', () => {
for (const assignment of SOURCE_ASSIGNMENTS) { for (const assignment of SOURCE_ASSIGNMENTS) {
const body = fs.readFileSync(ownerModule(assignment.source), 'utf8'); const body = fs.readFileSync(ownerModule(assignment.source), 'utf8');
@@ -63,9 +78,12 @@ describe('GStack 2 canonical skill UX', () => {
const bootstrap = fs.readFileSync(path.join(ROOT, 'skills', tree, 'references', 'support', 'runtime-bootstrap.mjs')); const bootstrap = fs.readFileSync(path.join(ROOT, 'skills', tree, 'references', 'support', 'runtime-bootstrap.mjs'));
const browserChoice = fs.readFileSync(path.join(ROOT, 'skills', tree, 'references', 'support', 'browser-choice.mjs')); const browserChoice = fs.readFileSync(path.join(ROOT, 'skills', tree, 'references', 'support', 'browser-choice.mjs'));
const contract = JSON.parse(fs.readFileSync(path.join(ROOT, 'skills', tree, 'references', 'support', 'runtime-contract.json'), 'utf8')); const contract = JSON.parse(fs.readFileSync(path.join(ROOT, 'skills', tree, 'references', 'support', 'runtime-contract.json'), 'utf8'));
const resultContract = JSON.parse(fs.readFileSync(path.join(ROOT, 'skills', tree, 'references', 'support', 'execution-result-contract.json'), 'utf8'));
expect(bootstrap, tree).toEqual(source); expect(bootstrap, tree).toEqual(source);
expect(browserChoice, tree).toEqual(fs.readFileSync(path.join(ROOT, 'runtime', 'browser-choice.mjs'))); expect(browserChoice, tree).toEqual(fs.readFileSync(path.join(ROOT, 'runtime', 'browser-choice.mjs')));
expect(contract, tree).toEqual({ schemaVersion: 1, runtimeVersion: '2.0.0', skillApi: '2.0' }); expect(contract, tree).toEqual({ schemaVersion: 1, runtimeVersion: '2.0.0', skillApi: '2.0' });
expect(resultContract.properties.status.enum, tree).toEqual(['success', 'degraded', 'unsupported', 'failed']);
expect(resultContract.allOf[0].then.properties.evidence.minItems, tree).toBe(1);
expect(runtime, tree).toContain('preview --capability <name>'); expect(runtime, tree).toContain('preview --capability <name>');
expect(runtime, tree).toContain('It never downloads components or mutates runtime state.'); expect(runtime, tree).toContain('It never downloads components or mutates runtime state.');
expect(runtime, tree).toContain('options --capability <name>'); expect(runtime, tree).toContain('options --capability <name>');
+35
View File
@@ -24,6 +24,41 @@ describe('GStack 2 structured dispatch', () => {
expect(routeStructured({ ...scenario.signals })).toEqual(original); expect(routeStructured({ ...scenario.signals })).toEqual(original);
}); });
test('infers readiness only from bounded structured operating conditions', () => {
const readiness = routeStructured({
surface: 'web',
implementation_exists: true,
evidence_need: 'readiness',
scope: 'narrow',
deployment_state: 'pre-deployment',
});
expect(readiness.depth).toBe('readiness');
expect(readiness.active_modules).toEqual(['qa-only']);
expect(routeStructured({
surface: 'web',
implementation_exists: true,
evidence_need: 'readiness',
scope: 'broad',
}).depth).not.toBe('readiness');
});
test('risk and deployment evidence promote work to deep', () => {
expect(routeStructured({ surface: 'web', implementation_exists: true, risk: 'high' }).depth)
.toBe('deep');
expect(routeStructured({ surface: 'web', implementation_exists: true, deployment_state: 'production' }).depth)
.toBe('deep');
expect(routeStructured({ surface: 'web', implementation_exists: true, mutation_scope: 'consequential' }).depth)
.toBe('deep');
expect(routeStructured({
surface: 'web',
implementation_exists: true,
evidence_need: 'readiness',
scope: 'narrow',
irreversible: true,
}).depth).toBe('deep');
});
test('explicit mutation denials override otherwise mutating modes', () => { test('explicit mutation denials override otherwise mutating modes', () => {
const review = routeStructured({ audit_focus: 'broad', mutation_authorized: false }); const review = routeStructured({ audit_focus: 'broad', mutation_authorized: false });
expect(review.mode).toBe('Normal'); expect(review.mode).toBe('Normal');
+19
View File
@@ -12,6 +12,7 @@ describe("release and CI hardening", () => {
for (const name of fs.readdirSync(workflowRoot).filter((entry) => entry.endsWith(".yml"))) { for (const name of fs.readdirSync(workflowRoot).filter((entry) => entry.endsWith(".yml"))) {
const source = fs.readFileSync(path.join(workflowRoot, name), "utf8"); const source = fs.readFileSync(path.join(workflowRoot, name), "utf8");
expect(source, `${name} must declare top-level permissions`).toMatch(/^permissions:\s*$/m); expect(source, `${name} must declare top-level permissions`).toMatch(/^permissions:\s*$/m);
expect(source, `${name} must declare workflow concurrency`).toMatch(/^concurrency:\s*$/m);
for (const match of source.matchAll(/\buses:\s*[^\s@]+@([^\s#]+)/g)) { for (const match of source.matchAll(/\buses:\s*[^\s@]+@([^\s#]+)/g)) {
expect(match[1], `${name} contains a mutable action ref`).toMatch(/^[a-f0-9]{40}$/); expect(match[1], `${name} contains a mutable action ref`).toMatch(/^[a-f0-9]{40}$/);
} }
@@ -24,6 +25,24 @@ describe("release and CI hardening", () => {
expect(source.match(new RegExp(guard.replaceAll(".", "\\."), "g"))?.length).toBeGreaterThanOrEqual(3); expect(source.match(new RegExp(guard.replaceAll(".", "\\."), "g"))?.length).toBeGreaterThanOrEqual(3);
}); });
test("public dependency and repository security workflows stay enabled and least-privileged", () => {
const dependencyReview = read(".github/workflows/dependency-review.yml");
expect(dependencyReview).toContain("actions/dependency-review-action@");
expect(dependencyReview).toContain("fail-on-severity: high");
expect(dependencyReview).not.toContain("pull_request_target:");
const osv = read(".github/workflows/osv-scanner.yml");
expect(osv).toContain("google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@");
expect(osv).toContain("security-events: write");
expect(osv).toContain("schedule:");
const scorecard = read(".github/workflows/scorecard.yml");
expect(scorecard).toContain("ossf/scorecard-action@");
expect(scorecard).toContain("github/codeql-action/upload-sarif@");
expect(scorecard).toContain("publish_results: false");
expect(scorecard).not.toContain("id-token: write");
});
test("npm package is an explicit small runtime-control surface", () => { test("npm package is an explicit small runtime-control surface", () => {
const pkg = JSON.parse(read("package.json")); const pkg = JSON.parse(read("package.json"));
expect(pkg.version).toBe(read("VERSION").trim()); expect(pkg.version).toBe(read("VERSION").trim());
+11
View File
@@ -5,6 +5,7 @@ import * as os from 'os';
import { import {
DEFAULT_MAX_FILES_PER_SHARD, DEFAULT_MAX_FILES_PER_SHARD,
FREE_TEST_ROOTS, FREE_TEST_ROOTS,
buildShardArgs,
isFreeTestFile, isFreeTestFile,
collectFreeTestFiles, collectFreeTestFiles,
containsScheduledProcessExitZero, containsScheduledProcessExitZero,
@@ -138,6 +139,16 @@ describe('test-free-shards: sharding', () => {
expect(() => assignFilesToShards(['a.test.ts'], -1)).toThrow(); expect(() => assignFilesToShards(['a.test.ts'], -1)).toThrow();
}); });
test('buildShardArgs accepts a suite-specific timeout without enabling file concurrency', () => {
expect(buildShardArgs(['test/gstack2-skills.test.ts'], 30_000)).toEqual([
'test',
'test/gstack2-skills.test.ts',
'--max-concurrency=1',
'--timeout=30000',
]);
expect(() => buildShardArgs(['test/example.test.ts'], 0)).toThrow();
});
test('shards are stable across runs (same files always land in same shard)', () => { test('shards are stable across runs (same files always land in same shard)', () => {
const files = ['x.test.ts', 'y.test.ts', 'z.test.ts']; const files = ['x.test.ts', 'y.test.ts', 'z.test.ts'];
const a = assignFilesToShards(files, 5); const a = assignFilesToShards(files, 5);