railcode 0.1.23 → 0.1.24
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 +1 -1
- package/dist/connections.js +24 -1
- package/dist/connectors.js +4 -1
- package/dist/index.js +13 -4
- package/dist/observability.js +1 -1
- package/package.json +1 -1
- package/static/sdk.js +76 -8
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ railcode roles <list|create|update|delete|add-member|remove-member|grants|grant|
|
|
|
32
32
|
Org roles + the granular grants table (admin)
|
|
33
33
|
railcode apps <list|show|access|set-access|transfer|delete> ...
|
|
34
34
|
Apps + access policy (owner/admin)
|
|
35
|
-
railcode analytics <app> [--range 7d|30d|90d] Per-app pageview analytics
|
|
35
|
+
railcode analytics <app> [--range 1d|7d|30d|90d] Per-app pageview analytics
|
|
36
36
|
railcode logs <connector|service-connector|llm|email|agent> [filters]
|
|
37
37
|
Org observability logs (admin)
|
|
38
38
|
```
|
package/dist/connections.js
CHANGED
|
@@ -83,12 +83,16 @@ export function parseAuthType(value) {
|
|
|
83
83
|
}
|
|
84
84
|
return v;
|
|
85
85
|
}
|
|
86
|
+
// A null content_type is a pre-default row: the proxy still sends application/json with
|
|
87
|
+
// any body, so show the effective value rather than a bare "-".
|
|
88
|
+
export const DEFAULT_CONTENT_TYPE = "application/json";
|
|
86
89
|
export function serviceConnectorAdminTable(list) {
|
|
87
|
-
return formatTable(["name", "base_url", "auth", "cred", "methods", "enabled", "native"], list.map((c) => [
|
|
90
|
+
return formatTable(["name", "base_url", "auth", "cred", "content_type", "methods", "enabled", "native"], list.map((c) => [
|
|
88
91
|
c.name,
|
|
89
92
|
c.base_url,
|
|
90
93
|
c.auth_type,
|
|
91
94
|
c.has_credential ? "yes" : "no",
|
|
95
|
+
c.content_type || DEFAULT_CONTENT_TYPE,
|
|
92
96
|
(c.allowed_methods ?? []).join(", ") || "all",
|
|
93
97
|
c.enabled ? "yes" : "no",
|
|
94
98
|
c.native_key ?? "-",
|
|
@@ -141,11 +145,30 @@ export function buildServiceConnectorCreateBody(input) {
|
|
|
141
145
|
body.auth_config = input.authConfig;
|
|
142
146
|
if (input.description !== undefined)
|
|
143
147
|
body.description = input.description;
|
|
148
|
+
// Omitted → the server stores application/json. Only send the field when the caller
|
|
149
|
+
// actually chose a type (e.g. a form-encoded API).
|
|
150
|
+
if (input.contentType !== undefined)
|
|
151
|
+
body.content_type = parseContentType(input.contentType);
|
|
144
152
|
if (input.allowedMethods && input.allowedMethods.length > 0) {
|
|
145
153
|
body.allowed_methods = input.allowedMethods;
|
|
146
154
|
}
|
|
147
155
|
return body;
|
|
148
156
|
}
|
|
157
|
+
// `--content-type <type>`: a single header value, so no CR/LF and nothing blank (an
|
|
158
|
+
// empty value would read as "unset" server-side — just leave the flag off for that).
|
|
159
|
+
export function parseContentType(value) {
|
|
160
|
+
const text = value.trim();
|
|
161
|
+
if (!text) {
|
|
162
|
+
throw new ConnectionAdminError("--content-type requires a value (e.g. application/x-www-form-urlencoded); omit it for application/json.");
|
|
163
|
+
}
|
|
164
|
+
if (/[\r\n]/.test(text)) {
|
|
165
|
+
throw new ConnectionAdminError("--content-type must not contain newlines.");
|
|
166
|
+
}
|
|
167
|
+
if (text.length > 255) {
|
|
168
|
+
throw new ConnectionAdminError("--content-type must be 255 characters or fewer.");
|
|
169
|
+
}
|
|
170
|
+
return text;
|
|
171
|
+
}
|
|
149
172
|
export function parseMethodList(value) {
|
|
150
173
|
if (value === undefined || value.trim() === "")
|
|
151
174
|
return [];
|
package/dist/connectors.js
CHANGED
|
@@ -49,7 +49,10 @@ export function connectorOpenapiOutput(docs) {
|
|
|
49
49
|
// API docs (link or inline), and the OpenAPI spec (link or inline) when present.
|
|
50
50
|
export function renderConnectorDocs(docs) {
|
|
51
51
|
const methods = (docs.allowed_methods ?? []).join(", ") || "(all)";
|
|
52
|
-
const
|
|
52
|
+
const identity = [`${docs.name} (${docs.auth_type}) — methods: ${methods}`];
|
|
53
|
+
if (docs.content_type)
|
|
54
|
+
identity.push(`body Content-Type: ${docs.content_type}`);
|
|
55
|
+
const sections = [identity.join("\n")];
|
|
53
56
|
if (docs.description)
|
|
54
57
|
sections.push(docs.description);
|
|
55
58
|
const hasAny = docs.usage_instructions ||
|
package/dist/index.js
CHANGED
|
@@ -54,7 +54,7 @@ Usage:
|
|
|
54
54
|
railcode roles <list|create|update|delete|add-member|remove-member|grants|grant|revoke|materialize|effective|catalog> ...
|
|
55
55
|
Manage org roles + the granular grants table (admin)
|
|
56
56
|
railcode apps <list|show|access|set-access|transfer|delete> ... Manage apps + access policy
|
|
57
|
-
railcode analytics <app> [--range 7d|30d|90d] Per-app pageview analytics (admin/owner)
|
|
57
|
+
railcode analytics <app> [--range 1d|7d|30d|90d] Per-app pageview analytics (admin/owner)
|
|
58
58
|
railcode logs <connector|service-connector|llm|email|agent> [filters]
|
|
59
59
|
Read org observability logs (admin)
|
|
60
60
|
railcode --version
|
|
@@ -4740,15 +4740,22 @@ Admin (service-connector:manage):
|
|
|
4740
4740
|
railcode connector enable <key> --credentials '{...}'
|
|
4741
4741
|
One-click enable/rotate a native preset
|
|
4742
4742
|
railcode connector create --name <n> --base-url <url> [--auth-type <t>]
|
|
4743
|
-
[--auth-config '{...}'] [--methods GET,POST] [--description <d>]
|
|
4743
|
+
[--auth-config '{...}'] [--methods GET,POST] [--description <d>]
|
|
4744
|
+
[--content-type <type>] [--disabled]
|
|
4744
4745
|
Create/replace a custom connector
|
|
4745
4746
|
railcode connector delete <name|uuid> Delete a service connector
|
|
4746
4747
|
|
|
4747
4748
|
Aliases: connector = connectors; list = ls, connectors; docs = doc; fetch = request.
|
|
4748
4749
|
|
|
4750
|
+
Create options:
|
|
4751
|
+
--content-type <type> Content-Type sent with request bodies
|
|
4752
|
+
(default application/json; e.g.
|
|
4753
|
+
application/x-www-form-urlencoded for a form API)
|
|
4754
|
+
|
|
4749
4755
|
List options:
|
|
4750
4756
|
--admin Manage view: base_url, credential + enabled
|
|
4751
|
-
state, native key
|
|
4757
|
+
state, content type, native key
|
|
4758
|
+
(service-connector:manage)
|
|
4752
4759
|
--json Print the raw connector array
|
|
4753
4760
|
|
|
4754
4761
|
Docs options:
|
|
@@ -4846,6 +4853,7 @@ async function commandConnectorCreate(args) {
|
|
|
4846
4853
|
"authConfig",
|
|
4847
4854
|
"authConfigFile",
|
|
4848
4855
|
"description",
|
|
4856
|
+
"contentType",
|
|
4849
4857
|
"methods",
|
|
4850
4858
|
"disabled",
|
|
4851
4859
|
"apiUrl",
|
|
@@ -4860,6 +4868,7 @@ async function commandConnectorCreate(args) {
|
|
|
4860
4868
|
authType,
|
|
4861
4869
|
authConfig,
|
|
4862
4870
|
description: optionString(args, "description"),
|
|
4871
|
+
contentType: optionString(args, "contentType"),
|
|
4863
4872
|
allowedMethods: parseMethodList(optionString(args, "methods")),
|
|
4864
4873
|
enabled: args.options.disabled !== true,
|
|
4865
4874
|
});
|
|
@@ -5692,7 +5701,7 @@ async function commandAppsDelete(args) {
|
|
|
5692
5701
|
const ANALYTICS_HELP = `railcode analytics — per-app pageview analytics (admin/owner)
|
|
5693
5702
|
|
|
5694
5703
|
Usage:
|
|
5695
|
-
railcode analytics <app> [--range 7d|30d|90d] Views, uniques, daily, top paths/users
|
|
5704
|
+
railcode analytics <app> [--range 1d|7d|30d|90d] Views, uniques, daily, top paths/users
|
|
5696
5705
|
|
|
5697
5706
|
<app> is an app slug or UUID. Default range 30d.
|
|
5698
5707
|
|
package/dist/observability.js
CHANGED
|
@@ -177,7 +177,7 @@ export function logTable(stream, rows) {
|
|
|
177
177
|
return formatTable(stream.columns, rows.map((r) => stream.map(r)));
|
|
178
178
|
}
|
|
179
179
|
// ── Analytics (per-app pageviews) ───────────────────────────────────────────
|
|
180
|
-
export const ANALYTICS_RANGES = ["7d", "30d", "90d"];
|
|
180
|
+
export const ANALYTICS_RANGES = ["1d", "7d", "30d", "90d"];
|
|
181
181
|
export function parseRange(value) {
|
|
182
182
|
if (value === undefined)
|
|
183
183
|
return undefined;
|
package/package.json
CHANGED
package/static/sdk.js
CHANGED
|
@@ -82,6 +82,7 @@
|
|
|
82
82
|
localStorage.setItem("__sdk_open", v ? "1" : "0");
|
|
83
83
|
root.getElementById("panel").style.display = v ? "flex" : "none";
|
|
84
84
|
applyWidth();
|
|
85
|
+
window.dispatchEvent(new CustomEvent("railcode:inspector", { detail: { open: v } }));
|
|
85
86
|
}
|
|
86
87
|
var escMap = { "&": "&", "<": "<", ">": ">" };
|
|
87
88
|
var escHtml = (s) => String(s == null ? "" : s).replace(/[&<>]/g, (c) => escMap[c]);
|
|
@@ -106,7 +107,9 @@
|
|
|
106
107
|
if (entries.length > 100) entries.shift();
|
|
107
108
|
render();
|
|
108
109
|
},
|
|
109
|
-
update: render
|
|
110
|
+
update: render,
|
|
111
|
+
toggle: () => setOpen(!isOpen),
|
|
112
|
+
isOpen: () => isOpen
|
|
110
113
|
};
|
|
111
114
|
|
|
112
115
|
// ../sdk/src/config.ts
|
|
@@ -219,14 +222,84 @@
|
|
|
219
222
|
}();
|
|
220
223
|
}
|
|
221
224
|
|
|
225
|
+
// ../sdk/src/identity.ts
|
|
226
|
+
var me = () => track("me", "me()", () => call("GET", "/me"));
|
|
227
|
+
var appUsers = () => track("app-users", "appUsers()", () => call("GET", "/app-users"));
|
|
228
|
+
var roles = () => track("roles", "roles()", () => call("GET", "/roles"));
|
|
229
|
+
|
|
230
|
+
// ../sdk/src/debug-fab.ts
|
|
231
|
+
function mount2() {
|
|
232
|
+
const host2 = document.createElement("div");
|
|
233
|
+
host2.id = "__sdk_debug_fab";
|
|
234
|
+
const root2 = host2.attachShadow({ mode: "open" });
|
|
235
|
+
root2.innerHTML = `
|
|
236
|
+
<style>
|
|
237
|
+
:host { all: initial; }
|
|
238
|
+
button {
|
|
239
|
+
box-sizing: border-box; position: fixed; right: 16px; bottom: 16px;
|
|
240
|
+
width: 36px; height: 36px; border-radius: 50%; display: flex;
|
|
241
|
+
align-items: center; justify-content: center; cursor: pointer; padding: 0;
|
|
242
|
+
background: #14171c; color: #d6d9de; border: 1px solid #2c333d;
|
|
243
|
+
box-shadow: 0 2px 10px rgba(0,0,0,.35); z-index: 2147483001;
|
|
244
|
+
}
|
|
245
|
+
button:hover { background: #1c2128; color: #fff; }
|
|
246
|
+
svg { width: 16px; height: 16px; }
|
|
247
|
+
</style>
|
|
248
|
+
<button title="SDK activity (Ctrl+\`)" aria-label="Toggle SDK activity">
|
|
249
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
250
|
+
stroke-linecap="round" stroke-linejoin="round">
|
|
251
|
+
<path d="M12 19h8"></path>
|
|
252
|
+
<path d="m4 17 6-6-6-6"></path>
|
|
253
|
+
</svg>
|
|
254
|
+
</button>`;
|
|
255
|
+
root2.querySelector("button").onclick = () => Inspector.toggle();
|
|
256
|
+
(document.body || document.documentElement).appendChild(host2);
|
|
257
|
+
const sync = () => {
|
|
258
|
+
host2.style.display = Inspector.isOpen() ? "none" : "";
|
|
259
|
+
};
|
|
260
|
+
sync();
|
|
261
|
+
window.addEventListener("railcode:inspector", sync);
|
|
262
|
+
}
|
|
263
|
+
me().then((who) => {
|
|
264
|
+
if (who.user.is_admin) mount2();
|
|
265
|
+
}).catch(() => {
|
|
266
|
+
});
|
|
267
|
+
|
|
222
268
|
// ../sdk/src/agents.ts
|
|
223
|
-
|
|
269
|
+
var TERMINAL = ["success", "failed", "cancelled", "limit_exceeded"];
|
|
270
|
+
var POLL_MIN_MS = 400;
|
|
271
|
+
var POLL_MAX_MS = 2e3;
|
|
272
|
+
var POLL_BACKOFF = 1.4;
|
|
273
|
+
function isFinished(run) {
|
|
274
|
+
return TERMINAL.includes(run.status);
|
|
275
|
+
}
|
|
276
|
+
async function doStart(name, input) {
|
|
224
277
|
return call("POST", `/agents/${encodeURIComponent(name)}`, { body: { input } });
|
|
225
278
|
}
|
|
279
|
+
async function doGet(requestId) {
|
|
280
|
+
return call("GET", `/agents/runs/${encodeURIComponent(requestId)}`);
|
|
281
|
+
}
|
|
282
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
283
|
+
async function doInvoke(name, input) {
|
|
284
|
+
let run = await doStart(name, input);
|
|
285
|
+
let wait = POLL_MIN_MS;
|
|
286
|
+
while (!isFinished(run)) {
|
|
287
|
+
await sleep(wait);
|
|
288
|
+
wait = Math.min(wait * POLL_BACKOFF, POLL_MAX_MS);
|
|
289
|
+
run = await doGet(run.request_id);
|
|
290
|
+
}
|
|
291
|
+
return run;
|
|
292
|
+
}
|
|
293
|
+
function start(name, input) {
|
|
294
|
+
return track("agents", `agents.start(${q(name)})`, () => doStart(name, input));
|
|
295
|
+
}
|
|
296
|
+
function get(requestId) {
|
|
297
|
+
return doGet(requestId);
|
|
298
|
+
}
|
|
226
299
|
function invoke(name, input) {
|
|
227
300
|
return track("agents", `agents.invoke(${q(name)})`, () => doInvoke(name, input));
|
|
228
301
|
}
|
|
229
|
-
var agents = { invoke };
|
|
302
|
+
var agents = { invoke, start, get };
|
|
230
303
|
|
|
231
304
|
// ../sdk/src/databases.ts
|
|
232
305
|
var QUERY_LABEL_MAX = 80;
|
|
@@ -567,11 +640,6 @@
|
|
|
567
640
|
delete: shared2.delete
|
|
568
641
|
};
|
|
569
642
|
|
|
570
|
-
// ../sdk/src/identity.ts
|
|
571
|
-
var me = () => track("me", "me()", () => call("GET", "/me"));
|
|
572
|
-
var appUsers = () => track("app-users", "appUsers()", () => call("GET", "/app-users"));
|
|
573
|
-
var roles = () => track("roles", "roles()", () => call("GET", "/roles"));
|
|
574
|
-
|
|
575
643
|
// ../sdk/src/llm.ts
|
|
576
644
|
function label2(method, input, opts = {}) {
|
|
577
645
|
const preview = typeof input === "string" ? shorten(input.replace(/\s+/g, " ").trim(), 70) : `${input.length} message${input.length === 1 ? "" : "s"}`;
|