@runtypelabs/cli 2.11.0 → 2.11.2
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/index.js +87 -3
- package/package.json +2 -3
package/dist/index.js
CHANGED
|
@@ -19803,7 +19803,11 @@ var require_fpo_schema = __commonJS({
|
|
|
19803
19803
|
var setupInstructionsSchema = zod_1.z.object({
|
|
19804
19804
|
summary: zod_1.z.string().min(1),
|
|
19805
19805
|
steps: zod_1.z.array(zod_1.z.string()),
|
|
19806
|
-
|
|
19806
|
+
// Constrained to an absolute URL because this lands in the rendered
|
|
19807
|
+
// `<a href={…}>` in the secret intake and quick-start preview UIs —
|
|
19808
|
+
// `javascript:` / `data:` schemes in an unrestricted string would be a
|
|
19809
|
+
// live XSS vector when a malicious template is imported.
|
|
19810
|
+
docsUrl: zod_1.z.string().url().optional()
|
|
19807
19811
|
});
|
|
19808
19812
|
var toolAuthSchema = zod_1.z.object({
|
|
19809
19813
|
type: zod_1.z.enum(["oauth", "api_key", "none", "user_provided"]),
|
|
@@ -20073,12 +20077,59 @@ var require_capability_validator = __commonJS({
|
|
|
20073
20077
|
}
|
|
20074
20078
|
});
|
|
20075
20079
|
|
|
20080
|
+
// ../shared/dist/product-generation/secret-ref.js
|
|
20081
|
+
var require_secret_ref = __commonJS({
|
|
20082
|
+
"../shared/dist/product-generation/secret-ref.js"(exports) {
|
|
20083
|
+
"use strict";
|
|
20084
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20085
|
+
exports.extractSecretReferences = extractSecretReferences;
|
|
20086
|
+
exports.extractSecretReferencesFromAnyValue = extractSecretReferencesFromAnyValue;
|
|
20087
|
+
var SECRET_REF_PATTERN = /\{\{secret:([A-Z][A-Z0-9_]*[A-Z0-9])\}\}/g;
|
|
20088
|
+
function extractSecretReferences(template) {
|
|
20089
|
+
const keys = /* @__PURE__ */ new Set();
|
|
20090
|
+
let match;
|
|
20091
|
+
const regex = new RegExp(SECRET_REF_PATTERN.source, "g");
|
|
20092
|
+
while ((match = regex.exec(template)) !== null) {
|
|
20093
|
+
const key = match[1];
|
|
20094
|
+
if (key)
|
|
20095
|
+
keys.add(key);
|
|
20096
|
+
}
|
|
20097
|
+
return Array.from(keys);
|
|
20098
|
+
}
|
|
20099
|
+
function extractSecretReferencesFromAnyValue(value, maxDepth = 10) {
|
|
20100
|
+
const keys = /* @__PURE__ */ new Set();
|
|
20101
|
+
walk(value, 0);
|
|
20102
|
+
return Array.from(keys);
|
|
20103
|
+
function walk(v, depth) {
|
|
20104
|
+
if (depth > maxDepth)
|
|
20105
|
+
return;
|
|
20106
|
+
if (typeof v === "string") {
|
|
20107
|
+
for (const key of extractSecretReferences(v))
|
|
20108
|
+
keys.add(key);
|
|
20109
|
+
return;
|
|
20110
|
+
}
|
|
20111
|
+
if (Array.isArray(v)) {
|
|
20112
|
+
for (const item of v)
|
|
20113
|
+
walk(item, depth + 1);
|
|
20114
|
+
return;
|
|
20115
|
+
}
|
|
20116
|
+
if (v && typeof v === "object") {
|
|
20117
|
+
for (const inner of Object.values(v)) {
|
|
20118
|
+
walk(inner, depth + 1);
|
|
20119
|
+
}
|
|
20120
|
+
}
|
|
20121
|
+
}
|
|
20122
|
+
}
|
|
20123
|
+
}
|
|
20124
|
+
});
|
|
20125
|
+
|
|
20076
20126
|
// ../shared/dist/product-generation/validators/tool-validator.js
|
|
20077
20127
|
var require_tool_validator = __commonJS({
|
|
20078
20128
|
"../shared/dist/product-generation/validators/tool-validator.js"(exports) {
|
|
20079
20129
|
"use strict";
|
|
20080
20130
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20081
20131
|
exports.validateToolDefinition = validateToolDefinition;
|
|
20132
|
+
var secret_ref_1 = require_secret_ref();
|
|
20082
20133
|
var types_1 = require_types2();
|
|
20083
20134
|
function validateToolDefinition(tool, index) {
|
|
20084
20135
|
const result = (0, types_1.emptyResult)();
|
|
@@ -20090,13 +20141,30 @@ var require_tool_validator = __commonJS({
|
|
|
20090
20141
|
result.errors.push((0, types_1.createIssue)("error", "INTEGRATION_NO_PROVIDER", "Integration tools must have a provider", `${base}.provider`));
|
|
20091
20142
|
}
|
|
20092
20143
|
if (tool.auth) {
|
|
20144
|
+
const declaredKeys = /* @__PURE__ */ new Set();
|
|
20093
20145
|
if (tool.auth.secrets) {
|
|
20094
20146
|
for (const [i, secret] of tool.auth.secrets.entries()) {
|
|
20095
20147
|
if (!secret.key || secret.key.trim() === "") {
|
|
20096
20148
|
result.errors.push((0, types_1.createIssue)("error", "SECRET_KEY_EMPTY", "Secret key is required", `${base}.auth.secrets[${i}].key`));
|
|
20149
|
+
continue;
|
|
20097
20150
|
}
|
|
20151
|
+
declaredKeys.add(secret.key);
|
|
20152
|
+
}
|
|
20153
|
+
}
|
|
20154
|
+
const referencedKeys = new Set((0, secret_ref_1.extractSecretReferencesFromAnyValue)(tool.config));
|
|
20155
|
+
for (const key of referencedKeys) {
|
|
20156
|
+
if (!declaredKeys.has(key)) {
|
|
20157
|
+
result.errors.push((0, types_1.createIssue)("error", "SECRET_REFERENCE_UNDECLARED", `Tool config references \`{{secret:${key}}}\` but this tool does not declare it in \`auth.secrets\`.`, `${base}.auth.secrets`, `Add \`{ key: '${key}', required: true }\` to this tool's \`auth.secrets\`.`));
|
|
20098
20158
|
}
|
|
20099
20159
|
}
|
|
20160
|
+
for (const key of declaredKeys) {
|
|
20161
|
+
if (!referencedKeys.has(key)) {
|
|
20162
|
+
result.warnings.push((0, types_1.createIssue)("warning", "SECRET_DECLARED_BUT_UNREFERENCED", `Secret \`${key}\` is declared in \`auth.secrets\` but never referenced as \`{{secret:${key}}}\` in this tool's config.`, `${base}.auth.secrets`, `Either reference \`{{secret:${key}}}\` in the tool config or remove it from \`auth.secrets\`. Integrations that consume secrets outside the config (e.g. MCP servers) can ignore this warning.`));
|
|
20163
|
+
}
|
|
20164
|
+
}
|
|
20165
|
+
if (declaredKeys.size > 0 && tool.auth.setupRequired === false) {
|
|
20166
|
+
result.recommendations.push((0, types_1.createIssue)("recommendation", "SETUP_REQUIRED_IMPLIED", `Tool declares ${declaredKeys.size} secret(s) in \`auth.secrets\` but \`auth.setupRequired\` is false \u2014 pending secrets will not be surfaced in the intake flow.`, `${base}.auth.setupRequired`, "Set `auth.setupRequired: true` so these secrets are materialized as pending bindings and shown to the user after import."));
|
|
20167
|
+
}
|
|
20100
20168
|
}
|
|
20101
20169
|
result.valid = result.errors.length === 0;
|
|
20102
20170
|
return result;
|
|
@@ -20321,8 +20389,21 @@ var require_fpo_template = __commonJS({
|
|
|
20321
20389
|
version: zod_1.z.literal(exports.FULL_PRODUCT_OBJECT_TEMPLATE_VERSION),
|
|
20322
20390
|
productObject: fpo_schema_1.fullProductObjectSchema,
|
|
20323
20391
|
template: zod_1.z.object({
|
|
20324
|
-
variables: zod_1.z.array(exports.fpoTemplateVariableSchema).
|
|
20392
|
+
variables: zod_1.z.array(exports.fpoTemplateVariableSchema).max(50)
|
|
20325
20393
|
})
|
|
20394
|
+
}).superRefine((doc, ctx) => {
|
|
20395
|
+
const hasVariables = doc.template.variables.length > 0;
|
|
20396
|
+
const hasPendingSecretTool = doc.productObject.tools.some((tool) => {
|
|
20397
|
+
var _a, _b;
|
|
20398
|
+
return ((_a = tool.auth) === null || _a === void 0 ? void 0 : _a.setupRequired) === true && Array.isArray((_b = tool.auth) === null || _b === void 0 ? void 0 : _b.secrets) && tool.auth.secrets.length > 0;
|
|
20399
|
+
});
|
|
20400
|
+
if (!hasVariables && !hasPendingSecretTool) {
|
|
20401
|
+
ctx.addIssue({
|
|
20402
|
+
code: "custom",
|
|
20403
|
+
message: "Template must declare at least one template variable or at least one tool with `auth.setupRequired: true` and pending secrets.",
|
|
20404
|
+
path: ["template", "variables"]
|
|
20405
|
+
});
|
|
20406
|
+
}
|
|
20326
20407
|
});
|
|
20327
20408
|
function collectStringLeafPaths(value, path14 = []) {
|
|
20328
20409
|
if (typeof value === "string") {
|
|
@@ -20352,7 +20433,7 @@ var require_fpo_template = __commonJS({
|
|
|
20352
20433
|
const inner = value.slice(start + 2, end);
|
|
20353
20434
|
const separatorIndex = inner.indexOf("|");
|
|
20354
20435
|
const key = (separatorIndex === -1 ? inner : inner.slice(0, separatorIndex)).trim();
|
|
20355
|
-
if (key.length > 0) {
|
|
20436
|
+
if (key.length > 0 && !key.startsWith("secret:")) {
|
|
20356
20437
|
references.push({
|
|
20357
20438
|
key,
|
|
20358
20439
|
defaultValue: separatorIndex === -1 ? void 0 : inner.slice(separatorIndex + 1).trim(),
|
|
@@ -20534,6 +20615,9 @@ var require_fpo_template = __commonJS({
|
|
|
20534
20615
|
if (!referencedKeys.has(variable.key)) {
|
|
20535
20616
|
result.warnings.push((0, types_1.createIssue)("warning", "UNUSED_TEMPLATE_VARIABLE", `Template variable "${variable.key}" is declared but not used`, `template.variables.${variable.key}`));
|
|
20536
20617
|
}
|
|
20618
|
+
if (variable.inputType === "secret") {
|
|
20619
|
+
result.warnings.push((0, types_1.createIssue)("warning", "TEMPLATE_VARIABLE_SECRET_IS_UNSAFE", `Template variable "${variable.key}" uses \`inputType: 'secret'\`, which substitutes the supplied value literally into the product record at resolve time \u2014 the value ends up persisted in the database.`, `template.variables.${variable.key}.inputType`, `Prefer declaring pending secrets via the target tool's \`auth.secrets\` array and referencing the value as \`{{secret:${variable.key.toUpperCase()}}}\` so the secret is stored in the secrets vault instead of in the product object.`));
|
|
20620
|
+
}
|
|
20537
20621
|
}
|
|
20538
20622
|
const defaultsResolution = (_a = options.defaultsResolution) !== null && _a !== void 0 ? _a : resolveFPOTemplate(template);
|
|
20539
20623
|
const defaultsValidation = (0, types_1.mergeResults)((0, fpo_validator_1.validateFPO)(defaultsResolution.resolved), defaultsResolution.missingVariables.length > 0 ? {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runtypelabs/cli",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.2",
|
|
4
4
|
"description": "Command-line interface for Runtype AI platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -19,11 +19,10 @@
|
|
|
19
19
|
"oauth4webapi": "^3.8.5",
|
|
20
20
|
"open": "^10.1.0",
|
|
21
21
|
"react": "^19.2.4",
|
|
22
|
-
"uuid": "^9.0.1",
|
|
23
22
|
"micromatch": "^4.0.8",
|
|
24
23
|
"yaml": "^2.8.3",
|
|
25
24
|
"@runtypelabs/ink-components": "0.3.1",
|
|
26
|
-
"@runtypelabs/sdk": "1.17.
|
|
25
|
+
"@runtypelabs/sdk": "1.17.1",
|
|
27
26
|
"@runtypelabs/terminal-animations": "0.2.0"
|
|
28
27
|
},
|
|
29
28
|
"devDependencies": {
|