orionfold-relay 0.23.0 → 0.24.1
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/dist/cli.js +102 -26
- package/next.config.mjs +52 -1
- package/package.json +2 -1
- package/src/app/api/snapshots/[id]/restore/route.ts +6 -0
- package/src/app/api/snapshots/route.ts +6 -0
- 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 +1 -1
- 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-composer-hero.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 +3 -3
- 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 +4 -4
- 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/onboarding/runtime-preference-modal.tsx +39 -10
- package/src/components/packs/pack-update-button.tsx +1 -1
- package/src/components/profiles/profile-card.tsx +18 -8
- 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/lib/agents/runtime/ollama-adapter.ts +11 -6
- package/src/lib/agents/runtime/ollama-model-resolver.ts +76 -0
- package/src/lib/agents/runtime/openai-codex.ts +1 -1
- package/src/lib/apps/apps-events.ts +15 -0
- 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/ollama-engine.ts +17 -4
- 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/templates/relay-agency/pack.yaml +1 -1
- package/src/lib/packs/templates/relay-agency-pro/pack.yaml +32 -16
- 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/snapshots/snapshot-manager.ts +40 -6
- package/src/lib/theme.ts +23 -11
- 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/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({
|
|
@@ -5795,6 +5795,13 @@ __export(registry_exports3, {
|
|
|
5795
5795
|
import fs11 from "fs";
|
|
5796
5796
|
import path11 from "path";
|
|
5797
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
|
+
}
|
|
5798
5805
|
function scanDirectory(dir, isBuiltin2) {
|
|
5799
5806
|
const blueprints = /* @__PURE__ */ new Map();
|
|
5800
5807
|
if (!fs11.existsSync(dir)) return blueprints;
|
|
@@ -5829,8 +5836,13 @@ function loadAll() {
|
|
|
5829
5836
|
return all;
|
|
5830
5837
|
}
|
|
5831
5838
|
function ensureLoaded2() {
|
|
5839
|
+
if (blueprintCache && userDirMtimeMs() !== cachedDirMtimeMs) {
|
|
5840
|
+
blueprintCache = null;
|
|
5841
|
+
}
|
|
5832
5842
|
if (!blueprintCache) {
|
|
5843
|
+
cachedDirMtimeMs = userDirMtimeMs();
|
|
5833
5844
|
blueprintCache = loadAll();
|
|
5845
|
+
applyPluginBlueprints(blueprintCache);
|
|
5834
5846
|
}
|
|
5835
5847
|
return blueprintCache;
|
|
5836
5848
|
}
|
|
@@ -5878,30 +5890,35 @@ function deleteBlueprint(id) {
|
|
|
5878
5890
|
function getUserBlueprintsDir() {
|
|
5879
5891
|
return USER_BLUEPRINTS_DIR;
|
|
5880
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
|
+
}
|
|
5881
5898
|
function mergePluginBlueprints(entries) {
|
|
5882
5899
|
const cache = ensureLoaded2();
|
|
5883
5900
|
for (const entry of entries) {
|
|
5884
5901
|
cache.set(entry.blueprint.id, entry.blueprint);
|
|
5885
|
-
if (!
|
|
5886
|
-
|
|
5902
|
+
if (!pluginBlueprints.has(entry.pluginId)) {
|
|
5903
|
+
pluginBlueprints.set(entry.pluginId, /* @__PURE__ */ new Map());
|
|
5887
5904
|
}
|
|
5888
|
-
|
|
5905
|
+
pluginBlueprints.get(entry.pluginId).set(entry.blueprint.id, entry.blueprint);
|
|
5889
5906
|
}
|
|
5890
5907
|
}
|
|
5891
5908
|
function clearPluginBlueprints(pluginId) {
|
|
5892
5909
|
const cache = blueprintCache;
|
|
5893
|
-
const
|
|
5894
|
-
if (!
|
|
5895
|
-
if (cache) for (const id of
|
|
5896
|
-
|
|
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);
|
|
5897
5914
|
}
|
|
5898
5915
|
function clearAllPluginBlueprints() {
|
|
5899
|
-
for (const pluginId of Array.from(
|
|
5916
|
+
for (const pluginId of Array.from(pluginBlueprints.keys())) {
|
|
5900
5917
|
clearPluginBlueprints(pluginId);
|
|
5901
5918
|
}
|
|
5902
5919
|
}
|
|
5903
5920
|
function listPluginBlueprintIds(pluginId) {
|
|
5904
|
-
return Array.from(
|
|
5921
|
+
return Array.from(pluginBlueprints.get(pluginId)?.keys() ?? []);
|
|
5905
5922
|
}
|
|
5906
5923
|
function validateBlueprintRefs(bp, opts2) {
|
|
5907
5924
|
for (const step of bp.steps ?? []) {
|
|
@@ -5923,7 +5940,7 @@ function validateBlueprintRefs(bp, opts2) {
|
|
|
5923
5940
|
}
|
|
5924
5941
|
return { ok: true };
|
|
5925
5942
|
}
|
|
5926
|
-
var BUILTINS_DIR2, USER_BLUEPRINTS_DIR, blueprintCache,
|
|
5943
|
+
var BUILTINS_DIR2, USER_BLUEPRINTS_DIR, blueprintCache, cachedDirMtimeMs, pluginBlueprints;
|
|
5927
5944
|
var init_registry3 = __esm({
|
|
5928
5945
|
"src/lib/workflows/blueprints/registry.ts"() {
|
|
5929
5946
|
"use strict";
|
|
@@ -5941,7 +5958,8 @@ var init_registry3 = __esm({
|
|
|
5941
5958
|
);
|
|
5942
5959
|
USER_BLUEPRINTS_DIR = getAinativeBlueprintsDir();
|
|
5943
5960
|
blueprintCache = null;
|
|
5944
|
-
|
|
5961
|
+
cachedDirMtimeMs = null;
|
|
5962
|
+
pluginBlueprints = /* @__PURE__ */ new Map();
|
|
5945
5963
|
}
|
|
5946
5964
|
});
|
|
5947
5965
|
|
|
@@ -12945,7 +12963,7 @@ var init_registry6 = __esm({
|
|
|
12945
12963
|
init_registry5();
|
|
12946
12964
|
init_installer();
|
|
12947
12965
|
init_schedule_spec();
|
|
12948
|
-
SUPPORTED_API_VERSIONS = /* @__PURE__ */ new Set([CURRENT_PLUGIN_API_VERSION, "0.
|
|
12966
|
+
SUPPORTED_API_VERSIONS = /* @__PURE__ */ new Set([CURRENT_PLUGIN_API_VERSION, "0.23"]);
|
|
12949
12967
|
pluginCache = null;
|
|
12950
12968
|
lastLoadedPluginIds = /* @__PURE__ */ new Set();
|
|
12951
12969
|
PluginTableSchema = z16.object({
|
|
@@ -17617,11 +17635,20 @@ var init_plugin_spec_tools = __esm({
|
|
|
17617
17635
|
}
|
|
17618
17636
|
});
|
|
17619
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
|
+
|
|
17620
17647
|
// src/lib/chat/tools/app-view-tools.ts
|
|
17621
17648
|
import { z as z28 } from "zod";
|
|
17622
17649
|
function dispatchAppsChangedFromTool() {
|
|
17623
17650
|
if (typeof window !== "undefined") {
|
|
17624
|
-
window.dispatchEvent(new CustomEvent(
|
|
17651
|
+
window.dispatchEvent(new CustomEvent(APPS_CHANGED_EVENT));
|
|
17625
17652
|
}
|
|
17626
17653
|
}
|
|
17627
17654
|
function loadManifestOrError(appId) {
|
|
@@ -17758,6 +17785,7 @@ var init_app_view_tools = __esm({
|
|
|
17758
17785
|
"src/lib/chat/tools/app-view-tools.ts"() {
|
|
17759
17786
|
"use strict";
|
|
17760
17787
|
init_tool_registry();
|
|
17788
|
+
init_apps_events();
|
|
17761
17789
|
init_helpers2();
|
|
17762
17790
|
init_registry();
|
|
17763
17791
|
BindingsSchema = ViewSchema.shape.bindings;
|
|
@@ -20155,7 +20183,7 @@ async function handleServerRequest(client, taskId, request) {
|
|
|
20155
20183
|
contentItems: [
|
|
20156
20184
|
{
|
|
20157
20185
|
type: "inputText",
|
|
20158
|
-
text: "Dynamic tool calls are not supported by
|
|
20186
|
+
text: "Dynamic tool calls are not supported by Relay's Codex runtime yet."
|
|
20159
20187
|
}
|
|
20160
20188
|
]
|
|
20161
20189
|
});
|
|
@@ -21698,6 +21726,41 @@ var init_openai_direct = __esm({
|
|
|
21698
21726
|
}
|
|
21699
21727
|
});
|
|
21700
21728
|
|
|
21729
|
+
// src/lib/agents/runtime/ollama-model-resolver.ts
|
|
21730
|
+
async function listPulledOllamaModels(baseUrl) {
|
|
21731
|
+
try {
|
|
21732
|
+
const response = await fetch(`${baseUrl}/api/tags`, {
|
|
21733
|
+
signal: AbortSignal.timeout(5e3)
|
|
21734
|
+
});
|
|
21735
|
+
if (!response.ok) return [];
|
|
21736
|
+
const data = await response.json();
|
|
21737
|
+
return (data.models ?? []).map((m) => m.name).filter((n) => typeof n === "string" && n.length > 0);
|
|
21738
|
+
} catch {
|
|
21739
|
+
return [];
|
|
21740
|
+
}
|
|
21741
|
+
}
|
|
21742
|
+
async function resolveOllamaModel(baseUrl, requestedModel, defaultModel) {
|
|
21743
|
+
const explicit = requestedModel?.trim() || defaultModel?.trim();
|
|
21744
|
+
if (explicit) return explicit;
|
|
21745
|
+
const pulled = await listPulledOllamaModels(baseUrl);
|
|
21746
|
+
if (pulled.length > 0) return pulled[0];
|
|
21747
|
+
throw new OllamaModelNotConfiguredError();
|
|
21748
|
+
}
|
|
21749
|
+
var OllamaModelNotConfiguredError;
|
|
21750
|
+
var init_ollama_model_resolver = __esm({
|
|
21751
|
+
"src/lib/agents/runtime/ollama-model-resolver.ts"() {
|
|
21752
|
+
"use strict";
|
|
21753
|
+
OllamaModelNotConfiguredError = class extends Error {
|
|
21754
|
+
constructor(message) {
|
|
21755
|
+
super(
|
|
21756
|
+
message ?? "No Ollama model is configured. Pull a model (e.g. `ollama pull llama3.2`) or set a default in Settings \u2192 Ollama."
|
|
21757
|
+
);
|
|
21758
|
+
this.name = "OllamaModelNotConfiguredError";
|
|
21759
|
+
}
|
|
21760
|
+
};
|
|
21761
|
+
}
|
|
21762
|
+
});
|
|
21763
|
+
|
|
21701
21764
|
// src/lib/agents/runtime/ollama-adapter.ts
|
|
21702
21765
|
import { eq as eq38 } from "drizzle-orm";
|
|
21703
21766
|
async function getOllamaBaseUrl() {
|
|
@@ -21706,11 +21769,11 @@ async function getOllamaBaseUrl() {
|
|
|
21706
21769
|
const url = await getSetting2(SETTINGS_KEYS2.OLLAMA_BASE_URL);
|
|
21707
21770
|
return url || DEFAULT_OLLAMA_BASE_URL;
|
|
21708
21771
|
}
|
|
21709
|
-
async function getOllamaModel() {
|
|
21772
|
+
async function getOllamaModel(baseUrl) {
|
|
21710
21773
|
const { getSetting: getSetting2 } = await Promise.resolve().then(() => (init_helpers(), helpers_exports));
|
|
21711
21774
|
const { SETTINGS_KEYS: SETTINGS_KEYS2 } = await Promise.resolve().then(() => (init_settings(), settings_exports));
|
|
21712
|
-
const
|
|
21713
|
-
return
|
|
21775
|
+
const defaultModel = await getSetting2(SETTINGS_KEYS2.OLLAMA_DEFAULT_MODEL);
|
|
21776
|
+
return resolveOllamaModel(baseUrl, null, defaultModel);
|
|
21714
21777
|
}
|
|
21715
21778
|
async function streamOllamaChat(baseUrl, model, messages, signal) {
|
|
21716
21779
|
const response = await fetch(`${baseUrl}/api/chat`, {
|
|
@@ -21805,7 +21868,7 @@ async function executeOllamaTask(taskId) {
|
|
|
21805
21868
|
await db.update(tasks).set({ status: "running", updatedAt: /* @__PURE__ */ new Date() }).where(eq38(tasks.id, taskId));
|
|
21806
21869
|
const ctx = await buildTaskQueryContext(task, agentProfileId);
|
|
21807
21870
|
const baseUrl = await getOllamaBaseUrl();
|
|
21808
|
-
const modelId = await getOllamaModel();
|
|
21871
|
+
const modelId = await getOllamaModel(baseUrl);
|
|
21809
21872
|
const messages = [];
|
|
21810
21873
|
if (ctx.systemInstructions) {
|
|
21811
21874
|
messages.push({ role: "system", content: ctx.systemInstructions });
|
|
@@ -21896,7 +21959,7 @@ async function executeOllamaTask(taskId) {
|
|
|
21896
21959
|
}
|
|
21897
21960
|
async function runOllamaTaskAssist(input) {
|
|
21898
21961
|
const baseUrl = await getOllamaBaseUrl();
|
|
21899
|
-
const modelId = await getOllamaModel();
|
|
21962
|
+
const modelId = await getOllamaModel(baseUrl);
|
|
21900
21963
|
const profileIds = listProfiles().map((p) => p.id);
|
|
21901
21964
|
const profileList = profileIds.length > 0 ? `Available agent profiles: ${profileIds.join(", ")}` : "No explicit profiles available.";
|
|
21902
21965
|
const systemPrompt = `You are an AI task definition assistant. Analyze the given task and return ONLY a JSON object (no markdown) with:
|
|
@@ -21952,7 +22015,7 @@ async function testOllamaConnection() {
|
|
|
21952
22015
|
};
|
|
21953
22016
|
}
|
|
21954
22017
|
}
|
|
21955
|
-
var DEFAULT_OLLAMA_BASE_URL,
|
|
22018
|
+
var DEFAULT_OLLAMA_BASE_URL, ollamaRuntimeAdapter;
|
|
21956
22019
|
var init_ollama_adapter = __esm({
|
|
21957
22020
|
"src/lib/agents/runtime/ollama-adapter.ts"() {
|
|
21958
22021
|
"use strict";
|
|
@@ -21961,10 +22024,10 @@ var init_ollama_adapter = __esm({
|
|
|
21961
22024
|
init_execution_manager();
|
|
21962
22025
|
init_claude_agent();
|
|
21963
22026
|
init_catalog2();
|
|
22027
|
+
init_ollama_model_resolver();
|
|
21964
22028
|
init_registry2();
|
|
21965
22029
|
init_ledger();
|
|
21966
22030
|
DEFAULT_OLLAMA_BASE_URL = "http://localhost:11434";
|
|
21967
|
-
DEFAULT_OLLAMA_MODEL = "llama3.2";
|
|
21968
22031
|
ollamaRuntimeAdapter = {
|
|
21969
22032
|
metadata: getRuntimeCatalogEntry("ollama"),
|
|
21970
22033
|
async executeTask(taskId) {
|
|
@@ -25775,8 +25838,8 @@ import { execFileSync as execFileSync3 } from "child_process";
|
|
|
25775
25838
|
import yaml12 from "js-yaml";
|
|
25776
25839
|
import semver from "semver";
|
|
25777
25840
|
function relayCoreVersion() {
|
|
25778
|
-
if (semver.valid("0.
|
|
25779
|
-
return "0.
|
|
25841
|
+
if (semver.valid("0.24.1")) {
|
|
25842
|
+
return "0.24.1";
|
|
25780
25843
|
}
|
|
25781
25844
|
try {
|
|
25782
25845
|
const root = getAppRoot(import.meta.dirname, 3);
|
|
@@ -27147,7 +27210,8 @@ var __dirname = dirname5(fileURLToPath4(import.meta.url));
|
|
|
27147
27210
|
var appDir = join21(__dirname, "..");
|
|
27148
27211
|
var launchCwd2 = process.cwd();
|
|
27149
27212
|
var _envLocalPath = join21(launchCwd2, ".env.local");
|
|
27150
|
-
var
|
|
27213
|
+
var _hasDataDirFlag = process.argv.slice(2).some((a) => a === "--data-dir" || a.startsWith("--data-dir="));
|
|
27214
|
+
var _firstRunNeedsEnv = !existsSync13(_envLocalPath) && !process.env.RELAY_DATA_DIR && !_hasDataDirFlag && !isDevMode(launchCwd2);
|
|
27151
27215
|
if (_firstRunNeedsEnv) {
|
|
27152
27216
|
const folderName = basename6(launchCwd2);
|
|
27153
27217
|
const autoDataDir = join21(homedir8(), `.${folderName}`);
|
|
@@ -27187,6 +27251,18 @@ if (existsSync13(_envLocalPath)) {
|
|
|
27187
27251
|
}
|
|
27188
27252
|
}
|
|
27189
27253
|
}
|
|
27254
|
+
function scanDataDirFlag(argv) {
|
|
27255
|
+
for (let i = 0; i < argv.length; i++) {
|
|
27256
|
+
const tok = argv[i];
|
|
27257
|
+
if (tok === "--data-dir") return argv[i + 1];
|
|
27258
|
+
if (tok.startsWith("--data-dir=")) return tok.slice("--data-dir=".length);
|
|
27259
|
+
}
|
|
27260
|
+
return void 0;
|
|
27261
|
+
}
|
|
27262
|
+
var _dataDirFlag = scanDataDirFlag(process.argv.slice(2));
|
|
27263
|
+
if (_dataDirFlag) {
|
|
27264
|
+
process.env.RELAY_DATA_DIR = _dataDirFlag;
|
|
27265
|
+
}
|
|
27190
27266
|
var pkg = JSON.parse(readFileSync9(join21(appDir, "package.json"), "utf-8"));
|
|
27191
27267
|
function getHelpText() {
|
|
27192
27268
|
const dir = getAinativeDataDir();
|
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.1",
|
|
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
|
},
|
|
@@ -2,6 +2,7 @@ import { NextRequest, NextResponse } from "next/server";
|
|
|
2
2
|
import {
|
|
3
3
|
restoreFromSnapshot,
|
|
4
4
|
isSnapshotLocked,
|
|
5
|
+
SnapshotBusyError,
|
|
5
6
|
} from "@/lib/snapshots/snapshot-manager";
|
|
6
7
|
import { db } from "@/lib/db";
|
|
7
8
|
import { tasks } from "@/lib/db/schema";
|
|
@@ -51,6 +52,11 @@ export async function POST(
|
|
|
51
52
|
"Restore complete. Please restart the server to load the restored database.",
|
|
52
53
|
});
|
|
53
54
|
} catch (error) {
|
|
55
|
+
// Lock contention is a 409, not a server error — never conflate it with a
|
|
56
|
+
// genuine failure (issue #24).
|
|
57
|
+
if (error instanceof SnapshotBusyError) {
|
|
58
|
+
return NextResponse.json({ error: error.message }, { status: 409 });
|
|
59
|
+
}
|
|
54
60
|
return NextResponse.json(
|
|
55
61
|
{
|
|
56
62
|
error:
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
listSnapshots,
|
|
5
5
|
getSnapshotsSize,
|
|
6
6
|
isSnapshotLocked,
|
|
7
|
+
SnapshotBusyError,
|
|
7
8
|
} from "@/lib/snapshots/snapshot-manager";
|
|
8
9
|
|
|
9
10
|
/** GET /api/snapshots — list all snapshots with disk usage */
|
|
@@ -46,6 +47,11 @@ export async function POST(req: NextRequest) {
|
|
|
46
47
|
|
|
47
48
|
return NextResponse.json(snapshot, { status: 201 });
|
|
48
49
|
} catch (error) {
|
|
50
|
+
// A lock grabbed between the isSnapshotLocked() check and createSnapshot is
|
|
51
|
+
// still contention, not a server error (issue #24).
|
|
52
|
+
if (error instanceof SnapshotBusyError) {
|
|
53
|
+
return NextResponse.json({ error: error.message }, { status: 409 });
|
|
54
|
+
}
|
|
49
55
|
return NextResponse.json(
|
|
50
56
|
{ error: error instanceof Error ? error.message : "Failed to create snapshot" },
|
|
51
57
|
{ status: 500 }
|
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;
|
package/src/app/packs/page.tsx
CHANGED
|
@@ -81,7 +81,7 @@ export default async function PacksPage({
|
|
|
81
81
|
return (
|
|
82
82
|
<PageShell
|
|
83
83
|
title="Packs"
|
|
84
|
-
description="Vertical content bundles
|
|
84
|
+
description="Vertical content bundles. An app, profiles, blueprints, tables, and seed data installed in one step."
|
|
85
85
|
filters={
|
|
86
86
|
templates.length > 1 ? (
|
|
87
87
|
<FilterChips active={filter} counts={counts} />
|
|
@@ -11,7 +11,6 @@ import Link from "next/link";
|
|
|
11
11
|
import { FileText } from "lucide-react";
|
|
12
12
|
import { Sparkline } from "@/components/charts/sparkline";
|
|
13
13
|
import { getProjectCompletionTrend } from "@/lib/queries/chart-data";
|
|
14
|
-
import { EnvironmentSummaryCard } from "@/components/environment/environment-summary-card";
|
|
15
14
|
|
|
16
15
|
export const dynamic = "force-dynamic";
|
|
17
16
|
|
|
@@ -160,16 +159,6 @@ export default async function ProjectDetailPage({
|
|
|
160
159
|
</div>
|
|
161
160
|
)}
|
|
162
161
|
|
|
163
|
-
{/* Environment summary */}
|
|
164
|
-
{project.workingDirectory && (
|
|
165
|
-
<div className="mb-6">
|
|
166
|
-
<EnvironmentSummaryCard
|
|
167
|
-
projectId={id}
|
|
168
|
-
workingDirectory={project.workingDirectory}
|
|
169
|
-
/>
|
|
170
|
-
</div>
|
|
171
|
-
)}
|
|
172
|
-
|
|
173
162
|
{/* Recent documents */}
|
|
174
163
|
{recentDocs.length > 0 && (
|
|
175
164
|
<div className="mb-6">
|
|
@@ -100,7 +100,7 @@ function HeroVariant({ task, previousRuns }: HeroProps) {
|
|
|
100
100
|
if (!task) {
|
|
101
101
|
return (
|
|
102
102
|
<div className="surface-card rounded-xl p-6 text-center text-muted-foreground border">
|
|
103
|
-
No digest yet
|
|
103
|
+
No digest yet. Click <strong>Run now</strong> to generate the first one.
|
|
104
104
|
</div>
|
|
105
105
|
);
|
|
106
106
|
}
|
|
@@ -15,7 +15,7 @@ export function LedgerHeroPanel({ series, categories, period }: LedgerHeroPanelP
|
|
|
15
15
|
if (series.length === 0 && categories.length === 0) {
|
|
16
16
|
return (
|
|
17
17
|
<div className="surface-card rounded-xl p-12 text-center text-muted-foreground border">
|
|
18
|
-
No data yet
|
|
18
|
+
No data yet. Add transactions or click <strong>Run now</strong> to ingest a CSV.
|
|
19
19
|
</div>
|
|
20
20
|
);
|
|
21
21
|
}
|
|
@@ -16,7 +16,7 @@ const EXAMPLE_PROMPTS: { label: string; prompt: string }[] = [
|
|
|
16
16
|
{
|
|
17
17
|
label: "Build me a reading log…",
|
|
18
18
|
prompt:
|
|
19
|
-
"Build me a reading log. Track each book with title, author, date finished, and a 1
|
|
19
|
+
"Build me a reading log. Track each book with title, author, date finished, and a rating from 1 to 5. Every Friday at 5pm, summarize what I read this week.",
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
label: "Build me an expense tracker for my contractors…",
|
|
@@ -137,7 +137,7 @@ export function AppMaterializedCard({
|
|
|
137
137
|
))}
|
|
138
138
|
</ul>
|
|
139
139
|
<p className="text-[11px] text-muted-foreground/60 pt-1">
|
|
140
|
-
Informational
|
|
140
|
+
Informational. These files are written under your control. No approval required.
|
|
141
141
|
</p>
|
|
142
142
|
</div>
|
|
143
143
|
)}
|
|
@@ -193,7 +193,7 @@ export function AppViewEditorCard({
|
|
|
193
193
|
</p>
|
|
194
194
|
)}
|
|
195
195
|
{status === "cancelled" && (
|
|
196
|
-
<p className="text-xs text-muted-foreground">Cancelled
|
|
196
|
+
<p className="text-xs text-muted-foreground">Cancelled. No changes written.</p>
|
|
197
197
|
)}
|
|
198
198
|
{status === "failed" && errorMessage && (
|
|
199
199
|
<p className="text-xs text-destructive">Failed: {errorMessage}</p>
|
|
@@ -176,7 +176,7 @@ export function ChatCommandPopover({
|
|
|
176
176
|
const activeCount = Array.isArray(body.activeSkillIds)
|
|
177
177
|
? (body.activeSkillIds as string[]).length
|
|
178
178
|
: 1;
|
|
179
|
-
toast.success(`Added ${skillName}
|
|
179
|
+
toast.success(`Added ${skillName}. ${activeCount} skill${activeCount !== 1 ? "s" : ""} active`);
|
|
180
180
|
},
|
|
181
181
|
[conversationId, refetchActive]
|
|
182
182
|
);
|
|
@@ -494,7 +494,7 @@ function ToolCatalogItems({
|
|
|
494
494
|
const showDisabled = !isActive && !canAdd && !!onAddSkill;
|
|
495
495
|
const disabledReason = atCapacity
|
|
496
496
|
? `Max ${resolvedMax} skills active`
|
|
497
|
-
: "Single skill only on this runtime
|
|
497
|
+
: "Single skill only on this runtime. Switch runtime to compose";
|
|
498
498
|
|
|
499
499
|
return (
|
|
500
500
|
<SkillRow
|
|
@@ -97,10 +97,10 @@ export function ChatEmptyState({
|
|
|
97
97
|
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary/10">
|
|
98
98
|
<Bot className="h-6 w-6 text-primary" />
|
|
99
99
|
</div>
|
|
100
|
-
<h2 className="text-lg font-semibold">Describe an app.
|
|
100
|
+
<h2 className="text-lg font-semibold">Describe an app. Relay builds it.</h2>
|
|
101
101
|
<p className="text-sm text-muted-foreground text-center max-w-md">
|
|
102
|
-
|
|
103
|
-
Or ask anything about your workspace.
|
|
102
|
+
One prompt builds the whole app: profiles, blueprints, tables, and
|
|
103
|
+
schedules. Or ask anything about your workspace.
|
|
104
104
|
</p>
|
|
105
105
|
</div>
|
|
106
106
|
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
import { AlertCircle } from "lucide-react";
|
|
19
19
|
import { resolveModelLabel, type ChatQuestion, type QuickAccessItem, type ScreenshotAttachment } from "@/lib/chat/types";
|
|
20
20
|
import type { ComposedAppSummary } from "@/lib/apps/composition-detector";
|
|
21
|
+
import { APPS_CHANGED_EVENT } from "@/lib/apps/apps-events";
|
|
21
22
|
|
|
22
23
|
interface ExtensionFallbackSummary {
|
|
23
24
|
plugin: CreatePluginSpecInputForCard;
|
|
@@ -56,7 +57,7 @@ function ComposedAppCard({ app }: { app: ComposedAppSummary }) {
|
|
|
56
57
|
});
|
|
57
58
|
if (res.ok) {
|
|
58
59
|
setAppStatus("undone");
|
|
59
|
-
window.dispatchEvent(new CustomEvent(
|
|
60
|
+
window.dispatchEvent(new CustomEvent(APPS_CHANGED_EVENT));
|
|
60
61
|
}
|
|
61
62
|
}, [app.appId]);
|
|
62
63
|
|
|
@@ -331,7 +331,7 @@ export function ChatSessionProvider({ children }: { children: ReactNode }) {
|
|
|
331
331
|
void createConversation();
|
|
332
332
|
};
|
|
333
333
|
const handleCompact = () => {
|
|
334
|
-
toast.info("Compact is not wired yet
|
|
334
|
+
toast.info("Compact is not wired yet. Coming soon.");
|
|
335
335
|
};
|
|
336
336
|
const handleExport = async () => {
|
|
337
337
|
const activeConversationId = activeIdRef.current;
|
|
@@ -339,7 +339,7 @@ export function ChatSessionProvider({ children }: { children: ReactNode }) {
|
|
|
339
339
|
? messagesByConversationRef.current[activeConversationId]
|
|
340
340
|
: undefined;
|
|
341
341
|
if (!msgs || msgs.length === 0) {
|
|
342
|
-
toast.error("Nothing to export
|
|
342
|
+
toast.error("Nothing to export. This conversation is empty.");
|
|
343
343
|
return;
|
|
344
344
|
}
|
|
345
345
|
const title = `Chat — ${new Date().toISOString().slice(0, 10)}`;
|
|
@@ -325,7 +325,7 @@ function ParameterForm({
|
|
|
325
325
|
if (blueprint.variables.length === 0) {
|
|
326
326
|
return (
|
|
327
327
|
<p className="text-sm text-muted-foreground">
|
|
328
|
-
This blueprint has no parameters
|
|
328
|
+
This blueprint has no parameters. Starting a conversation now.
|
|
329
329
|
</p>
|
|
330
330
|
);
|
|
331
331
|
}
|