orionfold-relay 0.22.1 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/cli.js +139 -55
- package/drizzle.config.ts +2 -2
- package/next.config.mjs +52 -1
- package/package.json +2 -1
- package/src/app/api/license/route.ts +1 -1
- package/src/app/apps/page.tsx +1 -1
- package/src/app/inbox/page.tsx +1 -1
- package/src/app/layout.tsx +8 -3
- package/src/app/packs/page.tsx +255 -40
- package/src/app/projects/[id]/page.tsx +0 -11
- package/src/components/apps/last-run-card.tsx +1 -1
- package/src/components/apps/ledger-hero-panel.tsx +1 -1
- package/src/components/charts/time-series-chart.tsx +1 -1
- package/src/components/chat/app-materialized-card.tsx +1 -1
- package/src/components/chat/app-view-editor-card.tsx +1 -1
- package/src/components/chat/chat-command-popover.tsx +2 -2
- package/src/components/chat/chat-empty-state.tsx +1 -1
- package/src/components/chat/chat-message.tsx +2 -1
- package/src/components/chat/chat-session-provider.tsx +2 -2
- package/src/components/chat/conversation-template-picker.tsx +1 -1
- package/src/components/chat/skill-row.tsx +1 -15
- package/src/components/customers/customer-form-sheet.tsx +1 -1
- package/src/components/dashboard/greeting.tsx +1 -1
- package/src/components/dashboard/welcome-landing.tsx +2 -2
- package/src/components/documents/document-upload-dialog.tsx +1 -1
- package/src/components/documents/smart-extracted-text.tsx +1 -1
- package/src/components/instance/instance-section.tsx +1 -1
- package/src/components/instance/upgrade-badge.tsx +1 -1
- package/src/components/notifications/batch-proposal-review.tsx +1 -1
- package/src/components/notifications/inbox-list.tsx +41 -1
- package/src/components/notifications/unread-badge.tsx +28 -2
- package/src/components/onboarding/runtime-preference-modal.tsx +32 -3
- package/src/components/packs/pack-update-button.tsx +1 -1
- package/src/components/profiles/profile-detail-view.tsx +1 -1
- package/src/components/projects/project-create-dialog.tsx +1 -1
- package/src/components/projects/project-form-sheet.tsx +2 -2
- package/src/components/schedules/schedule-create-dialog.tsx +1 -1
- package/src/components/schedules/schedule-create-sheet.tsx +1 -1
- package/src/components/schedules/schedule-edit-sheet.tsx +1 -1
- package/src/components/schedules/schedule-form.tsx +1 -1
- package/src/components/settings/data-management-section.tsx +2 -2
- package/src/components/settings/database-snapshots-section.tsx +6 -6
- package/src/components/settings/ollama-section.tsx +2 -2
- package/src/components/settings/presets-section.tsx +2 -2
- package/src/components/settings/providers-runtimes-section.tsx +6 -6
- package/src/components/settings/web-search-section.tsx +1 -1
- package/src/components/shared/command-palette.tsx +2 -2
- package/src/components/shared/trust-tier-badge.tsx +3 -3
- package/src/components/shell/app-bar.tsx +156 -164
- package/src/components/shell/app-shell.tsx +16 -8
- package/src/components/shell/nav-items.ts +72 -30
- package/src/components/tasks/ai-assist-panel.tsx +2 -2
- package/src/components/tasks/task-create-panel.tsx +1 -1
- package/src/components/tasks/task-edit-dialog.tsx +1 -1
- package/src/components/workflows/blueprint-gallery.tsx +1 -1
- package/src/components/workflows/delay-step-body.tsx +1 -1
- package/src/components/workflows/workflow-confirmation-view.tsx +1 -1
- package/src/components/workflows/workflow-form-view.tsx +1 -1
- package/src/components/workspace/discover-workspace-dialog.tsx +1 -1
- package/src/instrumentation-node.ts +1 -1
- package/src/lib/agents/runtime/anthropic-direct.ts +72 -9
- package/src/lib/agents/runtime/openai-codex.ts +1 -1
- package/src/lib/apps/apps-events.ts +15 -0
- package/src/lib/apps/registry.ts +1 -1
- package/src/lib/apps/use-apps.ts +4 -3
- package/src/lib/channels/slack-adapter.ts +1 -1
- package/src/lib/channels/telegram-adapter.ts +1 -1
- package/src/lib/channels/webhook-adapter.ts +2 -2
- package/src/lib/chat/system-prompt.ts +4 -4
- package/src/lib/chat/tool-catalog.ts +3 -3
- package/src/lib/chat/tools/app-view-tools.ts +3 -2
- package/src/lib/data/seed-data/environment.ts +2 -2
- package/src/lib/db/bootstrap.ts +5 -1
- package/src/lib/packs/format.ts +38 -2
- package/src/lib/packs/templates/relay-agency/pack.yaml +2 -1
- package/src/lib/packs/templates/relay-agency-pro/pack.yaml +16 -7
- package/src/lib/plugins/examples/echo-server/plugin.yaml +1 -1
- package/src/lib/plugins/examples/finance-pack/plugin.yaml +1 -1
- package/src/lib/plugins/examples/reading-radar/plugin.yaml +1 -1
- package/src/lib/plugins/registry.ts +1 -1
- package/src/lib/plugins/sdk/types.ts +1 -1
- package/src/lib/theme.ts +23 -11
- package/src/lib/utils/migrate-to-ainative.ts +82 -41
- package/src/lib/workflows/blueprints/registry.ts +59 -10
- package/src/app/analytics/page.tsx +0 -40
- package/src/app/api/environment/artifacts/[id]/route.ts +0 -17
- package/src/app/api/environment/artifacts/route.ts +0 -33
- package/src/app/api/environment/checkpoints/[id]/route.ts +0 -86
- package/src/app/api/environment/checkpoints/route.ts +0 -80
- package/src/app/api/environment/profiles/create/route.ts +0 -28
- package/src/app/api/environment/profiles/suggest/route.ts +0 -41
- package/src/app/api/environment/scan/route.ts +0 -70
- package/src/app/api/environment/sync/history/route.ts +0 -20
- package/src/app/api/environment/sync/preview/route.ts +0 -27
- package/src/app/api/environment/sync/route.ts +0 -43
- package/src/app/api/environment/templates/[id]/route.ts +0 -34
- package/src/app/api/environment/templates/route.ts +0 -27
- package/src/app/environment/compare/page.tsx +0 -20
- package/src/app/environment/loading.tsx +0 -56
- package/src/app/environment/page.tsx +0 -61
- package/src/app/environment/skills/page.tsx +0 -20
- package/src/components/analytics/analytics-dashboard.tsx +0 -200
- package/src/components/environment/adoption-prompt.tsx +0 -76
- package/src/components/environment/artifact-card.tsx +0 -93
- package/src/components/environment/artifact-detail-sheet.tsx +0 -136
- package/src/components/environment/artifact-presence-cell.tsx +0 -44
- package/src/components/environment/category-filter-bar.tsx +0 -132
- package/src/components/environment/checkpoint-list.tsx +0 -169
- package/src/components/environment/comparison-matrix.tsx +0 -132
- package/src/components/environment/environment-dashboard.tsx +0 -248
- package/src/components/environment/environment-summary-card.tsx +0 -153
- package/src/components/environment/health-score-card.tsx +0 -86
- package/src/components/environment/persona-indicator.tsx +0 -43
- package/src/components/environment/profile-create-dialog.tsx +0 -178
- package/src/components/environment/project-diff-view.tsx +0 -59
- package/src/components/environment/project-scan-badge.tsx +0 -36
- package/src/components/environment/rollback-confirm-dialog.tsx +0 -105
- package/src/components/environment/scan-status-bar.tsx +0 -48
- package/src/components/environment/skill-catalog.tsx +0 -117
- package/src/components/environment/skill-detail-sheet.tsx +0 -106
- package/src/components/environment/skill-drift-indicator.tsx +0 -42
- package/src/components/environment/suggested-profiles.tsx +0 -162
- package/src/components/environment/summary-cards-row.tsx +0 -91
- package/src/components/environment/sync-action-buttons.tsx +0 -63
- package/src/components/environment/sync-preview-dialog.tsx +0 -205
- package/src/components/environment/template-list.tsx +0 -149
- package/src/components/environment/tool-comparison-view.tsx +0 -75
- package/src/lib/analytics/queries.ts +0 -207
- package/src/lib/environment/comparison.ts +0 -170
- package/src/lib/environment/health-scoring.ts +0 -162
- package/src/lib/environment/skill-portfolio.ts +0 -97
package/README.md
CHANGED
|
@@ -104,7 +104,7 @@ The governance is *in* the workflow, not bolted on. A blueprint is a fixed step
|
|
|
104
104
|
## Why it stays trustworthy
|
|
105
105
|
|
|
106
106
|
- **Local-first** — SQLite database, no cloud dependency, `npx orionfold-relay` and go
|
|
107
|
-
- **
|
|
107
|
+
- **Relay never sends your data to Orionfold** — no telemetry, no update checks, no license server; the complete outbound-network inventory is documented and code-linked in [docs/trust/data-flow.md](docs/trust/data-flow.md)
|
|
108
108
|
- **Your rules, enforced** — tool permissions, inbox approvals, and audit trails for every agent action
|
|
109
109
|
- **Your AI team** — 21 specialist profiles ready to deploy, each with instructions, tool policies, and runtime tuning
|
|
110
110
|
- **Know what you spend** — usage metering, budgets, and per-provider/per-model spend visibility on governed runs
|
|
@@ -134,8 +134,8 @@ relay license remove <license-id> # forget a license
|
|
|
134
134
|
|
|
135
135
|
- **Verification is 100% offline** — an Ed25519 signature check against keys embedded in
|
|
136
136
|
this repo ([`src/lib/licensing/verify.ts`](src/lib/licensing/verify.ts)). Relay never
|
|
137
|
-
|
|
138
|
-
air-gapped.
|
|
137
|
+
sends your data to Orionfold: no activation server, no telemetry, no network call of
|
|
138
|
+
any kind. Works air-gapped.
|
|
139
139
|
- **Your packs are yours forever. Renewal gets you the year's new and updated packs +
|
|
140
140
|
priority support.** An expired or removed license never re-locks content you already
|
|
141
141
|
installed — it only gates new premium installs and updates.
|
package/dist/cli.js
CHANGED
|
@@ -464,7 +464,7 @@ function bootstrapAinativeDatabase(sqlite3) {
|
|
|
464
464
|
sqlite3.exec(ddl);
|
|
465
465
|
} catch (err2) {
|
|
466
466
|
const msg = err2 instanceof Error ? err2.message : String(err2);
|
|
467
|
-
if (!msg.includes("duplicate column")) {
|
|
467
|
+
if (!msg.includes("duplicate column") && !msg.includes("no such table")) {
|
|
468
468
|
console.error("[bootstrap] ALTER TABLE failed:", msg);
|
|
469
469
|
}
|
|
470
470
|
}
|
|
@@ -1186,7 +1186,7 @@ var CURRENT_PLUGIN_API_VERSION, CAPABILITY_VALUES, ORIGIN_VALUES, PrimitivesBund
|
|
|
1186
1186
|
var init_types = __esm({
|
|
1187
1187
|
"src/lib/plugins/sdk/types.ts"() {
|
|
1188
1188
|
"use strict";
|
|
1189
|
-
CURRENT_PLUGIN_API_VERSION = "0.
|
|
1189
|
+
CURRENT_PLUGIN_API_VERSION = "0.24";
|
|
1190
1190
|
CAPABILITY_VALUES = ["fs", "net", "child_process", "env"];
|
|
1191
1191
|
ORIGIN_VALUES = ["ainative-internal", "third-party"];
|
|
1192
1192
|
PrimitivesBundleManifestSchema = z.object({
|
|
@@ -3739,9 +3739,25 @@ var init_format = __esm({
|
|
|
3739
3739
|
/**
|
|
3740
3740
|
* Premium display copy (D6). Offline strings rendered on the locked
|
|
3741
3741
|
* gallery card — the Website still owns actual pricing. Meaningful only
|
|
3742
|
-
* alongside `entitlement`; harmless on a free pack.
|
|
3742
|
+
* alongside `entitlement`; harmless on a free pack. Either a flat string
|
|
3743
|
+
* ("$499/year") or a two-phase offer ({ list, intro?, note? }) so a
|
|
3744
|
+
* founding/introductory price can render alongside the list price.
|
|
3745
|
+
* Render sites consume `packPrice()` — never branch on the raw shape.
|
|
3743
3746
|
*/
|
|
3744
|
-
price: z3.
|
|
3747
|
+
price: z3.union([
|
|
3748
|
+
z3.string().min(1),
|
|
3749
|
+
z3.object({
|
|
3750
|
+
list: z3.string().min(1),
|
|
3751
|
+
intro: z3.string().min(1).optional(),
|
|
3752
|
+
note: z3.string().min(1).optional()
|
|
3753
|
+
}).strict()
|
|
3754
|
+
]).optional(),
|
|
3755
|
+
/**
|
|
3756
|
+
* Card identity token — a lucide icon name rendered on the gallery card
|
|
3757
|
+
* (e.g. "briefcase"). Unknown tokens fall back to the default glyph;
|
|
3758
|
+
* never a remote asset.
|
|
3759
|
+
*/
|
|
3760
|
+
icon: z3.string().min(1).optional(),
|
|
3745
3761
|
/** Get-license CTA target on the locked card. */
|
|
3746
3762
|
purchaseUrl: z3.url().optional(),
|
|
3747
3763
|
/**
|
|
@@ -5779,6 +5795,13 @@ __export(registry_exports3, {
|
|
|
5779
5795
|
import fs11 from "fs";
|
|
5780
5796
|
import path11 from "path";
|
|
5781
5797
|
import yaml7 from "js-yaml";
|
|
5798
|
+
function userDirMtimeMs() {
|
|
5799
|
+
try {
|
|
5800
|
+
return fs11.statSync(USER_BLUEPRINTS_DIR).mtimeMs;
|
|
5801
|
+
} catch {
|
|
5802
|
+
return null;
|
|
5803
|
+
}
|
|
5804
|
+
}
|
|
5782
5805
|
function scanDirectory(dir, isBuiltin2) {
|
|
5783
5806
|
const blueprints = /* @__PURE__ */ new Map();
|
|
5784
5807
|
if (!fs11.existsSync(dir)) return blueprints;
|
|
@@ -5813,8 +5836,13 @@ function loadAll() {
|
|
|
5813
5836
|
return all;
|
|
5814
5837
|
}
|
|
5815
5838
|
function ensureLoaded2() {
|
|
5839
|
+
if (blueprintCache && userDirMtimeMs() !== cachedDirMtimeMs) {
|
|
5840
|
+
blueprintCache = null;
|
|
5841
|
+
}
|
|
5816
5842
|
if (!blueprintCache) {
|
|
5843
|
+
cachedDirMtimeMs = userDirMtimeMs();
|
|
5817
5844
|
blueprintCache = loadAll();
|
|
5845
|
+
applyPluginBlueprints(blueprintCache);
|
|
5818
5846
|
}
|
|
5819
5847
|
return blueprintCache;
|
|
5820
5848
|
}
|
|
@@ -5862,30 +5890,35 @@ function deleteBlueprint(id) {
|
|
|
5862
5890
|
function getUserBlueprintsDir() {
|
|
5863
5891
|
return USER_BLUEPRINTS_DIR;
|
|
5864
5892
|
}
|
|
5893
|
+
function applyPluginBlueprints(cache) {
|
|
5894
|
+
for (const byId of pluginBlueprints.values()) {
|
|
5895
|
+
for (const [id, bp] of byId) cache.set(id, bp);
|
|
5896
|
+
}
|
|
5897
|
+
}
|
|
5865
5898
|
function mergePluginBlueprints(entries) {
|
|
5866
5899
|
const cache = ensureLoaded2();
|
|
5867
5900
|
for (const entry of entries) {
|
|
5868
5901
|
cache.set(entry.blueprint.id, entry.blueprint);
|
|
5869
|
-
if (!
|
|
5870
|
-
|
|
5902
|
+
if (!pluginBlueprints.has(entry.pluginId)) {
|
|
5903
|
+
pluginBlueprints.set(entry.pluginId, /* @__PURE__ */ new Map());
|
|
5871
5904
|
}
|
|
5872
|
-
|
|
5905
|
+
pluginBlueprints.get(entry.pluginId).set(entry.blueprint.id, entry.blueprint);
|
|
5873
5906
|
}
|
|
5874
5907
|
}
|
|
5875
5908
|
function clearPluginBlueprints(pluginId) {
|
|
5876
5909
|
const cache = blueprintCache;
|
|
5877
|
-
const
|
|
5878
|
-
if (!
|
|
5879
|
-
if (cache) for (const id of
|
|
5880
|
-
|
|
5910
|
+
const byId = pluginBlueprints.get(pluginId);
|
|
5911
|
+
if (!byId) return;
|
|
5912
|
+
if (cache) for (const id of byId.keys()) cache.delete(id);
|
|
5913
|
+
pluginBlueprints.delete(pluginId);
|
|
5881
5914
|
}
|
|
5882
5915
|
function clearAllPluginBlueprints() {
|
|
5883
|
-
for (const pluginId of Array.from(
|
|
5916
|
+
for (const pluginId of Array.from(pluginBlueprints.keys())) {
|
|
5884
5917
|
clearPluginBlueprints(pluginId);
|
|
5885
5918
|
}
|
|
5886
5919
|
}
|
|
5887
5920
|
function listPluginBlueprintIds(pluginId) {
|
|
5888
|
-
return Array.from(
|
|
5921
|
+
return Array.from(pluginBlueprints.get(pluginId)?.keys() ?? []);
|
|
5889
5922
|
}
|
|
5890
5923
|
function validateBlueprintRefs(bp, opts2) {
|
|
5891
5924
|
for (const step of bp.steps ?? []) {
|
|
@@ -5907,7 +5940,7 @@ function validateBlueprintRefs(bp, opts2) {
|
|
|
5907
5940
|
}
|
|
5908
5941
|
return { ok: true };
|
|
5909
5942
|
}
|
|
5910
|
-
var BUILTINS_DIR2, USER_BLUEPRINTS_DIR, blueprintCache,
|
|
5943
|
+
var BUILTINS_DIR2, USER_BLUEPRINTS_DIR, blueprintCache, cachedDirMtimeMs, pluginBlueprints;
|
|
5911
5944
|
var init_registry3 = __esm({
|
|
5912
5945
|
"src/lib/workflows/blueprints/registry.ts"() {
|
|
5913
5946
|
"use strict";
|
|
@@ -5925,7 +5958,8 @@ var init_registry3 = __esm({
|
|
|
5925
5958
|
);
|
|
5926
5959
|
USER_BLUEPRINTS_DIR = getAinativeBlueprintsDir();
|
|
5927
5960
|
blueprintCache = null;
|
|
5928
|
-
|
|
5961
|
+
cachedDirMtimeMs = null;
|
|
5962
|
+
pluginBlueprints = /* @__PURE__ */ new Map();
|
|
5929
5963
|
}
|
|
5930
5964
|
});
|
|
5931
5965
|
|
|
@@ -12929,7 +12963,7 @@ var init_registry6 = __esm({
|
|
|
12929
12963
|
init_registry5();
|
|
12930
12964
|
init_installer();
|
|
12931
12965
|
init_schedule_spec();
|
|
12932
|
-
SUPPORTED_API_VERSIONS = /* @__PURE__ */ new Set([CURRENT_PLUGIN_API_VERSION, "0.
|
|
12966
|
+
SUPPORTED_API_VERSIONS = /* @__PURE__ */ new Set([CURRENT_PLUGIN_API_VERSION, "0.23"]);
|
|
12933
12967
|
pluginCache = null;
|
|
12934
12968
|
lastLoadedPluginIds = /* @__PURE__ */ new Set();
|
|
12935
12969
|
PluginTableSchema = z16.object({
|
|
@@ -17601,11 +17635,20 @@ var init_plugin_spec_tools = __esm({
|
|
|
17601
17635
|
}
|
|
17602
17636
|
});
|
|
17603
17637
|
|
|
17638
|
+
// src/lib/apps/apps-events.ts
|
|
17639
|
+
var APPS_CHANGED_EVENT;
|
|
17640
|
+
var init_apps_events = __esm({
|
|
17641
|
+
"src/lib/apps/apps-events.ts"() {
|
|
17642
|
+
"use strict";
|
|
17643
|
+
APPS_CHANGED_EVENT = "relay-apps-changed";
|
|
17644
|
+
}
|
|
17645
|
+
});
|
|
17646
|
+
|
|
17604
17647
|
// src/lib/chat/tools/app-view-tools.ts
|
|
17605
17648
|
import { z as z28 } from "zod";
|
|
17606
17649
|
function dispatchAppsChangedFromTool() {
|
|
17607
17650
|
if (typeof window !== "undefined") {
|
|
17608
|
-
window.dispatchEvent(new CustomEvent(
|
|
17651
|
+
window.dispatchEvent(new CustomEvent(APPS_CHANGED_EVENT));
|
|
17609
17652
|
}
|
|
17610
17653
|
}
|
|
17611
17654
|
function loadManifestOrError(appId) {
|
|
@@ -17742,6 +17785,7 @@ var init_app_view_tools = __esm({
|
|
|
17742
17785
|
"src/lib/chat/tools/app-view-tools.ts"() {
|
|
17743
17786
|
"use strict";
|
|
17744
17787
|
init_tool_registry();
|
|
17788
|
+
init_apps_events();
|
|
17745
17789
|
init_helpers2();
|
|
17746
17790
|
init_registry();
|
|
17747
17791
|
BindingsSchema = ViewSchema.shape.bindings;
|
|
@@ -20139,7 +20183,7 @@ async function handleServerRequest(client, taskId, request) {
|
|
|
20139
20183
|
contentItems: [
|
|
20140
20184
|
{
|
|
20141
20185
|
type: "inputText",
|
|
20142
|
-
text: "Dynamic tool calls are not supported by
|
|
20186
|
+
text: "Dynamic tool calls are not supported by Relay's Codex runtime yet."
|
|
20143
20187
|
}
|
|
20144
20188
|
]
|
|
20145
20189
|
});
|
|
@@ -20746,6 +20790,24 @@ async function withAnthropicDirectMcpServers(profileServers, browserServers, ext
|
|
|
20746
20790
|
relay: relayServer
|
|
20747
20791
|
};
|
|
20748
20792
|
}
|
|
20793
|
+
function mcpServersToAnthropicConnectors(mergedServers) {
|
|
20794
|
+
const connectors = [];
|
|
20795
|
+
for (const [name, config] of Object.entries(mergedServers)) {
|
|
20796
|
+
if (name === "relay") continue;
|
|
20797
|
+
const cfg = config;
|
|
20798
|
+
const url = cfg.url ?? cfg.server_url;
|
|
20799
|
+
if (typeof url !== "string" || url.length === 0) {
|
|
20800
|
+
continue;
|
|
20801
|
+
}
|
|
20802
|
+
const connector = { type: "url", url, name };
|
|
20803
|
+
for (const [key, value] of Object.entries(cfg)) {
|
|
20804
|
+
if (["url", "server_url", "command", "args", "env"].includes(key)) continue;
|
|
20805
|
+
if (typeof value === "string") connector[key] = value;
|
|
20806
|
+
}
|
|
20807
|
+
connectors.push(connector);
|
|
20808
|
+
}
|
|
20809
|
+
return connectors;
|
|
20810
|
+
}
|
|
20749
20811
|
async function getAnthropicSDK() {
|
|
20750
20812
|
if (!_sdk) {
|
|
20751
20813
|
_sdk = await import("@anthropic-ai/sdk");
|
|
@@ -20812,7 +20874,7 @@ async function callAnthropicModel(client, systemPrompt, messages, tools, signal,
|
|
|
20812
20874
|
budget_tokens: options.extendedThinking.budgetTokens ?? 1e4
|
|
20813
20875
|
};
|
|
20814
20876
|
}
|
|
20815
|
-
if (options.mcpServers &&
|
|
20877
|
+
if (options.mcpServers && options.mcpServers.length > 0) {
|
|
20816
20878
|
params.mcp_servers = options.mcpServers;
|
|
20817
20879
|
}
|
|
20818
20880
|
const stream = client.messages.stream(params, { signal });
|
|
@@ -20917,6 +20979,7 @@ ${outputInstructions}`;
|
|
|
20917
20979
|
pluginServers,
|
|
20918
20980
|
task.projectId
|
|
20919
20981
|
);
|
|
20982
|
+
const mcpConnectors = mcpServersToAnthropicConnectors(mergedMcpServers);
|
|
20920
20983
|
let initialMessages;
|
|
20921
20984
|
if (isResume) {
|
|
20922
20985
|
const snapshot = await loadSessionSnapshot(taskId);
|
|
@@ -20965,7 +21028,7 @@ ${outputInstructions}`;
|
|
|
20965
21028
|
enableCaching: true,
|
|
20966
21029
|
profileInstructions: profile?.skillMd,
|
|
20967
21030
|
extendedThinking: capOverrides?.extendedThinking,
|
|
20968
|
-
mcpServers:
|
|
21031
|
+
mcpServers: mcpConnectors
|
|
20969
21032
|
}
|
|
20970
21033
|
);
|
|
20971
21034
|
await saveSessionSnapshot(taskId, agentProfileId, [
|
|
@@ -25740,8 +25803,8 @@ import { execFileSync as execFileSync3 } from "child_process";
|
|
|
25740
25803
|
import yaml12 from "js-yaml";
|
|
25741
25804
|
import semver from "semver";
|
|
25742
25805
|
function relayCoreVersion() {
|
|
25743
|
-
if (semver.valid("0.
|
|
25744
|
-
return "0.
|
|
25806
|
+
if (semver.valid("0.24.0")) {
|
|
25807
|
+
return "0.24.0";
|
|
25745
25808
|
}
|
|
25746
25809
|
try {
|
|
25747
25810
|
const root = getAppRoot(import.meta.dirname, 3);
|
|
@@ -26984,6 +27047,10 @@ function hasSqliteHeader(path24) {
|
|
|
26984
27047
|
return false;
|
|
26985
27048
|
}
|
|
26986
27049
|
}
|
|
27050
|
+
var MIGRATION_CHAIN = [
|
|
27051
|
+
{ fromDir: ".stagent", toDir: ".ainative", fromDb: "stagent.db", toDb: "ainative.db" },
|
|
27052
|
+
{ fromDir: ".ainative", toDir: ".relay", fromDb: "ainative.db", toDb: "relay.db" }
|
|
27053
|
+
];
|
|
26987
27054
|
async function migrateLegacyData(options = {}) {
|
|
26988
27055
|
const home = options.home ?? homedir2();
|
|
26989
27056
|
const gitDir = options.gitDir ?? join6(process.cwd(), ".git");
|
|
@@ -26996,46 +27063,50 @@ async function migrateLegacyData(options = {}) {
|
|
|
26996
27063
|
keychainMigrated: false,
|
|
26997
27064
|
errors: []
|
|
26998
27065
|
};
|
|
26999
|
-
const
|
|
27000
|
-
const
|
|
27001
|
-
|
|
27002
|
-
|
|
27003
|
-
|
|
27004
|
-
|
|
27005
|
-
|
|
27006
|
-
|
|
27007
|
-
|
|
27008
|
-
|
|
27009
|
-
|
|
27010
|
-
|
|
27011
|
-
|
|
27012
|
-
|
|
27013
|
-
|
|
27014
|
-
|
|
27015
|
-
|
|
27066
|
+
const finalDir = join6(home, MIGRATION_CHAIN[MIGRATION_CHAIN.length - 1].toDir);
|
|
27067
|
+
const finalDbName = MIGRATION_CHAIN[MIGRATION_CHAIN.length - 1].toDb;
|
|
27068
|
+
for (const hop of MIGRATION_CHAIN) {
|
|
27069
|
+
const oldDir = join6(home, hop.fromDir);
|
|
27070
|
+
const newDir = join6(home, hop.toDir);
|
|
27071
|
+
if (existsSync4(oldDir) && !existsSync4(newDir)) {
|
|
27072
|
+
try {
|
|
27073
|
+
renameSync(oldDir, newDir);
|
|
27074
|
+
report.dirMigrated = true;
|
|
27075
|
+
log(`renamed ${oldDir} -> ${newDir}`);
|
|
27076
|
+
} catch (err2) {
|
|
27077
|
+
const e = err2;
|
|
27078
|
+
if (e.code === "EXDEV") {
|
|
27079
|
+
try {
|
|
27080
|
+
cpSync(oldDir, newDir, { recursive: true });
|
|
27081
|
+
rmSync2(oldDir, { recursive: true, force: true });
|
|
27082
|
+
report.dirMigrated = true;
|
|
27083
|
+
log(`copied ${oldDir} -> ${newDir} (cross-device fallback)`);
|
|
27084
|
+
} catch (copyErr) {
|
|
27085
|
+
report.errors.push(`dir copy failed: ${String(copyErr)}`);
|
|
27086
|
+
return report;
|
|
27087
|
+
}
|
|
27088
|
+
} else {
|
|
27089
|
+
report.errors.push(`dir rename failed: ${String(err2)}`);
|
|
27016
27090
|
return report;
|
|
27017
27091
|
}
|
|
27018
|
-
} else {
|
|
27019
|
-
report.errors.push(`dir rename failed: ${String(err2)}`);
|
|
27020
|
-
return report;
|
|
27021
27092
|
}
|
|
27022
27093
|
}
|
|
27023
|
-
|
|
27024
|
-
|
|
27025
|
-
|
|
27026
|
-
|
|
27027
|
-
|
|
27028
|
-
|
|
27029
|
-
|
|
27030
|
-
|
|
27031
|
-
|
|
27032
|
-
|
|
27033
|
-
|
|
27094
|
+
if (existsSync4(newDir)) {
|
|
27095
|
+
for (const suffix of ["", "-shm", "-wal"]) {
|
|
27096
|
+
const oldName = join6(newDir, `${hop.fromDb}${suffix}`);
|
|
27097
|
+
const newName = join6(newDir, `${hop.toDb}${suffix}`);
|
|
27098
|
+
if (existsSync4(oldName) && !existsSync4(newName)) {
|
|
27099
|
+
try {
|
|
27100
|
+
renameSync(oldName, newName);
|
|
27101
|
+
report.dbFilesRenamed++;
|
|
27102
|
+
} catch (err2) {
|
|
27103
|
+
report.errors.push(`db file rename failed (${suffix}): ${String(err2)}`);
|
|
27104
|
+
}
|
|
27034
27105
|
}
|
|
27035
27106
|
}
|
|
27036
27107
|
}
|
|
27037
27108
|
}
|
|
27038
|
-
const dbPath4 = join6(
|
|
27109
|
+
const dbPath4 = join6(finalDir, finalDbName);
|
|
27039
27110
|
if (existsSync4(dbPath4) && !hasSqliteHeader(dbPath4)) {
|
|
27040
27111
|
log(`skipping SQL migration \u2014 ${dbPath4} exists but lacks SQLite header`);
|
|
27041
27112
|
}
|
|
@@ -27104,7 +27175,8 @@ var __dirname = dirname5(fileURLToPath4(import.meta.url));
|
|
|
27104
27175
|
var appDir = join21(__dirname, "..");
|
|
27105
27176
|
var launchCwd2 = process.cwd();
|
|
27106
27177
|
var _envLocalPath = join21(launchCwd2, ".env.local");
|
|
27107
|
-
var
|
|
27178
|
+
var _hasDataDirFlag = process.argv.slice(2).some((a) => a === "--data-dir" || a.startsWith("--data-dir="));
|
|
27179
|
+
var _firstRunNeedsEnv = !existsSync13(_envLocalPath) && !process.env.RELAY_DATA_DIR && !_hasDataDirFlag && !isDevMode(launchCwd2);
|
|
27108
27180
|
if (_firstRunNeedsEnv) {
|
|
27109
27181
|
const folderName = basename6(launchCwd2);
|
|
27110
27182
|
const autoDataDir = join21(homedir8(), `.${folderName}`);
|
|
@@ -27144,6 +27216,18 @@ if (existsSync13(_envLocalPath)) {
|
|
|
27144
27216
|
}
|
|
27145
27217
|
}
|
|
27146
27218
|
}
|
|
27219
|
+
function scanDataDirFlag(argv) {
|
|
27220
|
+
for (let i = 0; i < argv.length; i++) {
|
|
27221
|
+
const tok = argv[i];
|
|
27222
|
+
if (tok === "--data-dir") return argv[i + 1];
|
|
27223
|
+
if (tok.startsWith("--data-dir=")) return tok.slice("--data-dir=".length);
|
|
27224
|
+
}
|
|
27225
|
+
return void 0;
|
|
27226
|
+
}
|
|
27227
|
+
var _dataDirFlag = scanDataDirFlag(process.argv.slice(2));
|
|
27228
|
+
if (_dataDirFlag) {
|
|
27229
|
+
process.env.RELAY_DATA_DIR = _dataDirFlag;
|
|
27230
|
+
}
|
|
27147
27231
|
var pkg = JSON.parse(readFileSync9(join21(appDir, "package.json"), "utf-8"));
|
|
27148
27232
|
function getHelpText() {
|
|
27149
27233
|
const dir = getAinativeDataDir();
|
package/drizzle.config.ts
CHANGED
|
@@ -2,13 +2,13 @@ import { defineConfig } from "drizzle-kit";
|
|
|
2
2
|
import { homedir } from "os";
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
|
|
5
|
-
const dataDir = process.env.
|
|
5
|
+
const dataDir = process.env.RELAY_DATA_DIR || join(homedir(), ".relay");
|
|
6
6
|
|
|
7
7
|
export default defineConfig({
|
|
8
8
|
schema: "./src/lib/db/schema.ts",
|
|
9
9
|
out: "./src/lib/db/migrations",
|
|
10
10
|
dialect: "sqlite",
|
|
11
11
|
dbCredentials: {
|
|
12
|
-
url: join(dataDir, "
|
|
12
|
+
url: join(dataDir, "relay.db"),
|
|
13
13
|
},
|
|
14
14
|
});
|
package/next.config.mjs
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import {
|
|
3
|
+
PHASE_PRODUCTION_BUILD,
|
|
4
|
+
PHASE_DEVELOPMENT_SERVER,
|
|
5
|
+
} from "next/constants.js";
|
|
6
|
+
|
|
1
7
|
// When the operator opts into LAN binding (`--hostname` to a non-loopback host,
|
|
2
8
|
// see bin/cli.ts), the CLI sets RELAY_ALLOW_LAN_ORIGINS=true. In dev mode Next
|
|
3
9
|
// otherwise blocks cross-origin requests to /_next/* dev assets from the LAN
|
|
@@ -16,6 +22,26 @@ const RFC1918_DEV_ORIGINS = [
|
|
|
16
22
|
];
|
|
17
23
|
const allowLanDevOrigins = process.env.RELAY_ALLOW_LAN_ORIGINS === "true";
|
|
18
24
|
|
|
25
|
+
// Build-time core version, mirroring tsup's `define` (tsup.config.ts). tsup
|
|
26
|
+
// only builds the CLI bundle (dist/cli.js), so WITHOUT this the Next.js server
|
|
27
|
+
// leaves `__RELAY_CORE_VERSION__` undefined — relayCoreVersion() then falls to
|
|
28
|
+
// its "0.0.0" default and every /packs UI install is rejected with
|
|
29
|
+
// `requires relay-core >=X, but this install is 0.0.0` (fix-packs-ui-install-
|
|
30
|
+
// core-version). We inject it via `compiler.defineServer` below, which Next
|
|
31
|
+
// applies to BOTH bundlers (webpack for `next build`, Turbopack for `next dev`)
|
|
32
|
+
// so the server resolves the real version exactly as the shipped CLI does.
|
|
33
|
+
// `defineServer` (not `define`) because relayCoreVersion() is server-only —
|
|
34
|
+
// keeps the value out of client bundles. Single source of truth: pkg.version.
|
|
35
|
+
//
|
|
36
|
+
// NOTE: pass the RAW version string, NOT `JSON.stringify(...)`. Next's
|
|
37
|
+
// `compiler.define` takes literal values and quotes them itself, unlike tsup's
|
|
38
|
+
// `define` which takes JS-source text. Stringifying here would inject the
|
|
39
|
+
// double-quoted `"0.23.0"`, which fails `semver.valid()` and silently falls
|
|
40
|
+
// back to the "0.0.0" default — reintroducing the exact bug this fixes.
|
|
41
|
+
const CORE_VERSION_DEFINE = JSON.parse(
|
|
42
|
+
readFileSync(new URL("./package.json", import.meta.url), "utf-8")
|
|
43
|
+
).version;
|
|
44
|
+
|
|
19
45
|
/** @type {import('next').NextConfig} */
|
|
20
46
|
const nextConfig = {
|
|
21
47
|
serverExternalPackages: ["better-sqlite3", "pdf-parse", "pdfjs-dist"],
|
|
@@ -41,4 +67,29 @@ const nextConfig = {
|
|
|
41
67
|
},
|
|
42
68
|
};
|
|
43
69
|
|
|
44
|
-
export
|
|
70
|
+
// Phase-aware export. `compiler.defineServer` is a COMPILE-TIME directive — it
|
|
71
|
+
// only does anything while a bundler runs (build + dev). At runtime `next start`
|
|
72
|
+
// re-reads this config but never recompiles, so the define is inert there AND
|
|
73
|
+
// Next's config validator emits a spurious "defineServer.__RELAY_CORE_VERSION__
|
|
74
|
+
// is missing, expected boolean" warning (a false positive from its union-error
|
|
75
|
+
// flattener — the string value is valid; see next/dist/shared/lib/zod.js). That
|
|
76
|
+
// warning would land in every customer's prod server log. So we attach
|
|
77
|
+
// defineServer ONLY in the build/dev phases, keeping the shipped `next start`
|
|
78
|
+
// path warning-free while the version is already baked into `.next`.
|
|
79
|
+
export default function config(phase) {
|
|
80
|
+
if (
|
|
81
|
+
phase === PHASE_PRODUCTION_BUILD ||
|
|
82
|
+
phase === PHASE_DEVELOPMENT_SERVER
|
|
83
|
+
) {
|
|
84
|
+
return {
|
|
85
|
+
...nextConfig,
|
|
86
|
+
compiler: {
|
|
87
|
+
...nextConfig.compiler,
|
|
88
|
+
defineServer: {
|
|
89
|
+
__RELAY_CORE_VERSION__: CORE_VERSION_DEFINE,
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return nextConfig;
|
|
95
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orionfold-relay",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Orionfold Relay — a local-first, multi-agent orchestration runtime and builder scaffold for AI-native work.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"test:e2e": "vitest run --config vitest.config.e2e.ts",
|
|
69
69
|
"test:ui": "vitest --ui",
|
|
70
70
|
"validate:tokens": "npx tsx design-system/validate-tokens.ts",
|
|
71
|
+
"check:price-drift": "node scripts/check-price-drift.mjs",
|
|
71
72
|
"sync-worktree": "bash bin/sync-worktree.sh",
|
|
72
73
|
"prepublishOnly": "npm run build:cli"
|
|
73
74
|
},
|
|
@@ -14,7 +14,7 @@ import type { SignedLicense } from "@/lib/licensing/verify";
|
|
|
14
14
|
* paste/upload activation path for UI-first users: the browser reads the
|
|
15
15
|
* fulfilment file client-side and ships the `{ payload, signature }` envelope
|
|
16
16
|
* as JSON. Verification is offline Ed25519 inside saveLicense; nothing here
|
|
17
|
-
*
|
|
17
|
+
* sends user data to Orionfold.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
const BodySchema = z.object({
|
package/src/app/apps/page.tsx
CHANGED
|
@@ -100,7 +100,7 @@ function EmptyHero({ starters }: { starters: ReturnType<typeof listStarters> })
|
|
|
100
100
|
<Sparkles className="h-10 w-10 text-primary mb-4" aria-hidden="true" />
|
|
101
101
|
<h2 className="text-lg font-semibold">Teach this instance a new job.</h2>
|
|
102
102
|
<p className="mt-2 max-w-md text-sm text-muted-foreground">
|
|
103
|
-
Describe the thing you do every week. Orionfold Relay composes a profile, blueprint, schedule, and tables into a running app
|
|
103
|
+
Describe the thing you do every week. Orionfold Relay composes a profile, blueprint, schedule, and tables into a running app. No code, no deploys.
|
|
104
104
|
</p>
|
|
105
105
|
<div className="mt-4 flex items-center gap-4">
|
|
106
106
|
<Link
|
package/src/app/inbox/page.tsx
CHANGED
|
@@ -69,7 +69,7 @@ export default async function InboxPage() {
|
|
|
69
69
|
return (
|
|
70
70
|
<PageShell
|
|
71
71
|
title="Inbox"
|
|
72
|
-
description="Governance command center
|
|
72
|
+
description="Governance command center. Review approvals, questions, and agent activity."
|
|
73
73
|
>
|
|
74
74
|
<GovernanceStats
|
|
75
75
|
pending={pendingCount}
|
package/src/app/layout.tsx
CHANGED
|
@@ -12,6 +12,7 @@ import { ChatSessionProvider } from "@/components/chat/chat-session-provider";
|
|
|
12
12
|
import { RuntimePreferenceBootstrapper } from "@/components/onboarding/runtime-preference-bootstrapper";
|
|
13
13
|
import {
|
|
14
14
|
DEFAULT_THEME,
|
|
15
|
+
LEGACY_THEME_COOKIE,
|
|
15
16
|
THEME_COOKIE,
|
|
16
17
|
isResolvedTheme,
|
|
17
18
|
type ResolvedTheme,
|
|
@@ -82,12 +83,16 @@ export default async function RootLayout({
|
|
|
82
83
|
}: {
|
|
83
84
|
children: React.ReactNode;
|
|
84
85
|
}) {
|
|
85
|
-
// Resolve theme server-side from the
|
|
86
|
+
// Resolve theme server-side from the relay-theme cookie. Every client-side
|
|
86
87
|
// theme toggle writes this cookie (see src/lib/theme.ts), so SSR stays in
|
|
87
88
|
// sync with the user's preference and there is no FOUC — and no pre-hydration
|
|
88
|
-
// <script> tag, which is what React 19 warns about.
|
|
89
|
+
// <script> tag, which is what React 19 warns about. Fall back to the legacy
|
|
90
|
+
// ainative-theme cookie so a returning pre-rebrand user does not flash the
|
|
91
|
+
// default theme before the client re-writes the new cookie.
|
|
89
92
|
const cookieStore = await cookies();
|
|
90
|
-
const cookieValue =
|
|
93
|
+
const cookieValue =
|
|
94
|
+
cookieStore.get(THEME_COOKIE)?.value ??
|
|
95
|
+
cookieStore.get(LEGACY_THEME_COOKIE)?.value;
|
|
91
96
|
const theme: ResolvedTheme = isResolvedTheme(cookieValue)
|
|
92
97
|
? cookieValue
|
|
93
98
|
: DEFAULT_THEME;
|