terse-cli 0.1.64 → 0.1.66
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/cliVersion.d.ts +5 -0
- package/dist/cliVersion.d.ts.map +1 -1
- package/dist/cliVersion.js +13 -0
- package/dist/cliVersion.js.map +1 -1
- package/dist/codegen.d.ts +15 -0
- package/dist/codegen.d.ts.map +1 -1
- package/dist/codegen.js +466 -81
- package/dist/codegen.js.map +1 -1
- package/dist/commands/completion.d.ts +0 -1
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/completion.js +0 -49
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/deployTheme.d.ts +28 -0
- package/dist/commands/deployTheme.d.ts.map +1 -0
- package/dist/commands/deployTheme.js +68 -0
- package/dist/commands/deployTheme.js.map +1 -0
- package/dist/commands/dev.d.ts +3 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +47 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/fsExec.d.ts +8 -0
- package/dist/commands/fsExec.d.ts.map +1 -0
- package/dist/commands/fsExec.js +46 -0
- package/dist/commands/fsExec.js.map +1 -0
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +4 -1
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +5 -0
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/serve.d.ts +1 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +2 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/terseCliTheme.d.ts +28 -0
- package/dist/commands/terseCliTheme.d.ts.map +1 -0
- package/dist/commands/terseCliTheme.js +68 -0
- package/dist/commands/terseCliTheme.js.map +1 -0
- package/dist/deploy.d.ts +2 -1
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +61 -38
- package/dist/deploy.js.map +1 -1
- package/dist/generate.d.ts +2 -1
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +67 -69
- package/dist/generate.js.map +1 -1
- package/dist/index.js +1 -4
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +2 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +45 -96
- package/dist/init.js.map +1 -1
- package/dist/integrate.d.ts +1 -0
- package/dist/integrate.d.ts.map +1 -1
- package/dist/integrate.js +191 -11
- package/dist/integrate.js.map +1 -1
- package/dist/nonInteractive.d.ts +4 -2
- package/dist/nonInteractive.d.ts.map +1 -1
- package/dist/nonInteractive.js +5 -2
- package/dist/nonInteractive.js.map +1 -1
- package/dist/perf.d.ts +9 -0
- package/dist/perf.d.ts.map +1 -0
- package/dist/perf.js +59 -0
- package/dist/perf.js.map +1 -0
- package/dist/providers/codegen.test.d.ts +2 -0
- package/dist/providers/codegen.test.d.ts.map +1 -0
- package/dist/providers/codegen.test.js +45 -0
- package/dist/providers/codegen.test.js.map +1 -0
- package/dist/providers/python/PythonProvider.js +1 -0
- package/dist/providers/python/PythonProvider.js.map +1 -1
- package/dist/providers/python/PythonProvider.test.d.ts +2 -0
- package/dist/providers/python/PythonProvider.test.d.ts.map +1 -0
- package/dist/providers/python/PythonProvider.test.js +169 -0
- package/dist/providers/python/PythonProvider.test.js.map +1 -0
- package/dist/providers/typescript/prepareCodegenData.test.d.ts +2 -0
- package/dist/providers/typescript/prepareCodegenData.test.d.ts.map +1 -0
- package/dist/providers/typescript/prepareCodegenData.test.js +54 -0
- package/dist/providers/typescript/prepareCodegenData.test.js.map +1 -0
- package/dist/run.d.ts +2 -11
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +42 -153
- package/dist/run.js.map +1 -1
- package/dist/sampleEventId.d.ts +0 -4
- package/dist/sampleEventId.d.ts.map +1 -1
- package/dist/sampleEventId.js +0 -4
- package/dist/sampleEventId.js.map +1 -1
- package/dist/shared/ApiRoutes.d.ts +19 -0
- package/dist/shared/ApiRoutes.d.ts.map +1 -1
- package/dist/shared/ApiRoutes.js +17 -1
- package/dist/shared/ApiRoutes.js.map +1 -1
- package/dist/shared/Configs.d.ts +24 -2
- package/dist/shared/Configs.d.ts.map +1 -1
- package/dist/shared/Configs.js +32 -2
- package/dist/shared/Configs.js.map +1 -1
- package/dist/shared/Integrations.d.ts +18 -1
- package/dist/shared/Integrations.d.ts.map +1 -1
- package/dist/shared/Integrations.js +10 -1
- package/dist/shared/Integrations.js.map +1 -1
- package/dist/shared/InvalidationKeys.d.ts +1 -0
- package/dist/shared/InvalidationKeys.d.ts.map +1 -1
- package/dist/shared/InvalidationKeys.js +3 -0
- package/dist/shared/InvalidationKeys.js.map +1 -1
- package/dist/shared/ModelEvents.d.ts +9 -0
- package/dist/shared/ModelEvents.d.ts.map +1 -1
- package/dist/shared/ModelEvents.js +15 -0
- package/dist/shared/ModelEvents.js.map +1 -1
- package/dist/shared/ToolDisplayUtils.d.ts.map +1 -1
- package/dist/shared/ToolDisplayUtils.js +107 -11
- package/dist/shared/ToolDisplayUtils.js.map +1 -1
- package/dist/shared/types.d.ts +1013 -108
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/types.js.map +1 -1
- package/dist/test.d.ts +2 -1
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +43 -23
- package/dist/test.js.map +1 -1
- package/dist/userConfig.d.ts +0 -2
- package/dist/userConfig.d.ts.map +1 -1
- package/dist/userConfig.js +2 -15
- package/dist/userConfig.js.map +1 -1
- package/dist/util.d.ts +2 -3
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +3 -3
- package/dist/util.js.map +1 -1
- package/package.json +3 -3
- package/templates/typescript/codegen/partials/skills-section.hbs +4 -4
- package/templates/typescript/init/src/terse.jobs.ts.hbs +15 -15
- package/dist/jsonOutput.d.ts +0 -19
- package/dist/jsonOutput.d.ts.map +0 -1
- package/dist/jsonOutput.js +0 -25
- package/dist/jsonOutput.js.map +0 -1
- package/dist/replay.d.ts +0 -3
- package/dist/replay.d.ts.map +0 -1
- package/dist/replay.js +0 -20
- package/dist/replay.js.map +0 -1
- package/dist/urls.d.ts +0 -3
- package/dist/urls.d.ts.map +0 -1
- package/dist/urls.js +0 -27
- package/dist/urls.js.map +0 -1
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { afterEach, beforeEach, describe, it, mock } from "node:test";
|
|
6
|
+
import { PythonProvider } from "./PythonProvider.js";
|
|
7
|
+
const JOB_REGISTRY_MARKER = "__TERSE_JOB_REGISTRY__=";
|
|
8
|
+
const CREATED_DIRS = [];
|
|
9
|
+
class ExitSignal extends Error {
|
|
10
|
+
code;
|
|
11
|
+
constructor(code) {
|
|
12
|
+
super(`process.exit(${code ?? 0})`);
|
|
13
|
+
this.code = code;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
class TestPythonProvider extends PythonProvider {
|
|
17
|
+
execStdout = "";
|
|
18
|
+
capturedScripts = [];
|
|
19
|
+
execCalls = [];
|
|
20
|
+
async execUvCommand(args, opts) {
|
|
21
|
+
this.execCalls.push({ args, cwd: opts.cwd, env: opts.env });
|
|
22
|
+
return { stdout: this.execStdout, stderr: "" };
|
|
23
|
+
}
|
|
24
|
+
async withTempPythonScript(source, fn) {
|
|
25
|
+
this.capturedScripts.push(source);
|
|
26
|
+
return fn("/tmp/terse-python-provider-test.py");
|
|
27
|
+
}
|
|
28
|
+
async ensureUvAvailable(_cwd) { }
|
|
29
|
+
}
|
|
30
|
+
describe("PythonProvider entry file resolution", () => {
|
|
31
|
+
const originalCwd = process.cwd();
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
mock.restoreAll();
|
|
34
|
+
});
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
process.chdir(originalCwd);
|
|
37
|
+
mock.restoreAll();
|
|
38
|
+
while (CREATED_DIRS.length > 0) {
|
|
39
|
+
const dir = CREATED_DIRS.pop();
|
|
40
|
+
if (dir)
|
|
41
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
it("loads the canonical default entry file from src/main.py", async () => {
|
|
45
|
+
const dir = createPythonProject({
|
|
46
|
+
"src/main.py": "from terse_sdk import Terse\napp = Terse()\n"
|
|
47
|
+
});
|
|
48
|
+
process.chdir(dir);
|
|
49
|
+
const provider = new TestPythonProvider();
|
|
50
|
+
provider.execStdout = buildRegistryPayload("default-job");
|
|
51
|
+
const registry = await provider.loadJobRegistry();
|
|
52
|
+
assert.deepEqual([...registry.keys()], ["default-job"]);
|
|
53
|
+
assert.match(provider.capturedScripts[0], /ENTRY_FILE = "src\/main\.py"/);
|
|
54
|
+
assert.deepEqual(provider.execCalls[0]?.args, ["run", "python", "/tmp/terse-python-provider-test.py"]);
|
|
55
|
+
assert.equal(fs.realpathSync(provider.execCalls[0]?.cwd ?? ""), fs.realpathSync(dir));
|
|
56
|
+
assert.match(provider.execCalls[0]?.env?.UV_CACHE_DIR ?? "", /terse-uv-cache$/);
|
|
57
|
+
});
|
|
58
|
+
it("prints guidance when the default entry file is missing", async () => {
|
|
59
|
+
const dir = createPythonProject({
|
|
60
|
+
"src/server.py": "from terse_sdk import Terse\napp = Terse()\n"
|
|
61
|
+
});
|
|
62
|
+
process.chdir(dir);
|
|
63
|
+
const provider = new TestPythonProvider();
|
|
64
|
+
const errors = [];
|
|
65
|
+
mock.method(console, "error", (...args) => {
|
|
66
|
+
errors.push(args.map(String).join(" "));
|
|
67
|
+
});
|
|
68
|
+
mock.method(process, "exit", (code) => {
|
|
69
|
+
throw new ExitSignal(code);
|
|
70
|
+
});
|
|
71
|
+
await assert.rejects(provider.loadJobRegistry(), (error) => error instanceof ExitSignal && error.code === 1);
|
|
72
|
+
const output = stripAnsi(errors.join("\n"));
|
|
73
|
+
assert.match(output, /default Python Terse entry file at src\/main\.py/);
|
|
74
|
+
assert.match(output, /register at least one job with @app\.job/);
|
|
75
|
+
assert.match(output, /terse test --entry-file src\/server\.py/);
|
|
76
|
+
assert.match(output, /terse run my-job --entry-file src\/server\.py --event-file \.\/event\.json/);
|
|
77
|
+
assert.match(output, /terse deploy --entry-file src\/server\.py/);
|
|
78
|
+
assert.equal(provider.execCalls.length, 0);
|
|
79
|
+
});
|
|
80
|
+
it("loads a non-canonical entry file when --entry-file is provided", async () => {
|
|
81
|
+
const dir = createPythonProject({
|
|
82
|
+
"src/server.py": "from terse_sdk import Terse\napp = Terse()\n"
|
|
83
|
+
});
|
|
84
|
+
process.chdir(dir);
|
|
85
|
+
const provider = new TestPythonProvider();
|
|
86
|
+
provider.execStdout = buildRegistryPayload("self-hosted-job");
|
|
87
|
+
const registry = await provider.loadJobRegistry("src/server.py");
|
|
88
|
+
assert.deepEqual([...registry.keys()], ["self-hosted-job"]);
|
|
89
|
+
assert.match(provider.capturedScripts[0], /ENTRY_FILE = "src\/server\.py"/);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
describe("PythonProvider GitHub codegen parity", () => {
|
|
93
|
+
it("renders GitHub.skill() with repositoryIds via PythonProvider.renderGeneratedCode()", () => {
|
|
94
|
+
const provider = new PythonProvider();
|
|
95
|
+
const code = provider.renderGeneratedCode(buildCodegenInput({
|
|
96
|
+
github: [
|
|
97
|
+
{
|
|
98
|
+
integration: {
|
|
99
|
+
id: "github-integration-id",
|
|
100
|
+
installation_id: 123,
|
|
101
|
+
account_name: "TerseAI"
|
|
102
|
+
},
|
|
103
|
+
repositories: [
|
|
104
|
+
{
|
|
105
|
+
id: 1076128380,
|
|
106
|
+
name: "Terse",
|
|
107
|
+
owner: "TerseAI",
|
|
108
|
+
fullName: "TerseAI/Terse"
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}));
|
|
114
|
+
assert.match(code, /class GitHub:/);
|
|
115
|
+
assert.match(code, /def skill\(\*, repos: Sequence\[GitHubRepo\]\) -> SkillConfig\[str\]:/);
|
|
116
|
+
assert.match(code, /integration_id='github-integration-id'/);
|
|
117
|
+
assert.match(code, /config_type='github'/);
|
|
118
|
+
assert.match(code, /repositoryIds=\[repo\.repository_id for repo in repos\]/);
|
|
119
|
+
});
|
|
120
|
+
it("does not emit GitHub helpers when no GitHub integration is present", () => {
|
|
121
|
+
const provider = new PythonProvider();
|
|
122
|
+
const code = provider.renderGeneratedCode(buildCodegenInput());
|
|
123
|
+
assert.doesNotMatch(code, /# === GitHub ===/);
|
|
124
|
+
assert.doesNotMatch(code, /def skill\(\*, repos: Sequence\[GitHubRepo\]\)/);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
function createPythonProject(files) {
|
|
128
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "terse-python-provider-"));
|
|
129
|
+
CREATED_DIRS.push(dir);
|
|
130
|
+
fs.writeFileSync(path.join(dir, "pyproject.toml"), ["[project]", 'name = "provider-test"', 'version = "0.0.1"', 'requires-python = ">=3.11"', "dependencies = []", ""].join("\n"), "utf-8");
|
|
131
|
+
for (const [relativePath, contents] of Object.entries(files)) {
|
|
132
|
+
const filePath = path.join(dir, relativePath);
|
|
133
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
134
|
+
fs.writeFileSync(filePath, contents, "utf-8");
|
|
135
|
+
}
|
|
136
|
+
return dir;
|
|
137
|
+
}
|
|
138
|
+
function buildRegistryPayload(jobName) {
|
|
139
|
+
return `${JOB_REGISTRY_MARKER}${JSON.stringify({
|
|
140
|
+
[jobName]: {
|
|
141
|
+
name: jobName,
|
|
142
|
+
triggers: [],
|
|
143
|
+
skills: [],
|
|
144
|
+
toolApprovals: [],
|
|
145
|
+
hasFilter: false
|
|
146
|
+
}
|
|
147
|
+
})}`;
|
|
148
|
+
}
|
|
149
|
+
function stripAnsi(value) {
|
|
150
|
+
return value.replace(/\u001B\[[0-9;]*m/g, "");
|
|
151
|
+
}
|
|
152
|
+
function buildCodegenInput(overrides = {}) {
|
|
153
|
+
return {
|
|
154
|
+
github: [],
|
|
155
|
+
slack: [],
|
|
156
|
+
gmail: [],
|
|
157
|
+
linear: [],
|
|
158
|
+
notion: [],
|
|
159
|
+
posthog: [],
|
|
160
|
+
datadog: [],
|
|
161
|
+
launchdarkly: [],
|
|
162
|
+
workos: [],
|
|
163
|
+
attio: [],
|
|
164
|
+
snowflake: [],
|
|
165
|
+
tools: [],
|
|
166
|
+
...overrides
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=PythonProvider.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PythonProvider.test.js","sourceRoot":"","sources":["../../../src/providers/python/PythonProvider.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepareCodegenData.test.d.ts","sourceRoot":"","sources":["../../../src/providers/typescript/prepareCodegenData.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import { jsonSchemaToTs } from "./prepareCodegenData.js";
|
|
4
|
+
test("required nullable properties render as optional while preserving null", () => {
|
|
5
|
+
const schema = {
|
|
6
|
+
type: "object",
|
|
7
|
+
properties: {
|
|
8
|
+
thread_ts: {
|
|
9
|
+
anyOf: [{ type: "string" }, { type: "null" }],
|
|
10
|
+
},
|
|
11
|
+
blocks: {
|
|
12
|
+
anyOf: [{ type: "string" }, { type: "null" }],
|
|
13
|
+
},
|
|
14
|
+
message: {
|
|
15
|
+
type: "string",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
required: ["thread_ts", "blocks", "message"],
|
|
19
|
+
};
|
|
20
|
+
assert.equal(jsonSchemaToTs(schema, 0), `{
|
|
21
|
+
thread_ts?: string | null
|
|
22
|
+
blocks?: string | null
|
|
23
|
+
message: string
|
|
24
|
+
}`);
|
|
25
|
+
});
|
|
26
|
+
test("optional nullable properties stay optional", () => {
|
|
27
|
+
const schema = {
|
|
28
|
+
type: "object",
|
|
29
|
+
properties: {
|
|
30
|
+
cursor: {
|
|
31
|
+
anyOf: [{ type: "string" }, { type: "null" }],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
required: [],
|
|
35
|
+
};
|
|
36
|
+
assert.equal(jsonSchemaToTs(schema, 0), `{
|
|
37
|
+
cursor?: string | null
|
|
38
|
+
}`);
|
|
39
|
+
});
|
|
40
|
+
test("required non-nullable properties stay required", () => {
|
|
41
|
+
const schema = {
|
|
42
|
+
type: "object",
|
|
43
|
+
properties: {
|
|
44
|
+
channelId: {
|
|
45
|
+
type: "string",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
required: ["channelId"],
|
|
49
|
+
};
|
|
50
|
+
assert.equal(jsonSchemaToTs(schema, 0), `{
|
|
51
|
+
channelId: string
|
|
52
|
+
}`);
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=prepareCodegenData.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepareCodegenData.test.js","sourceRoot":"","sources":["../../../src/providers/typescript/prepareCodegenData.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAA;AACvC,OAAO,IAAI,MAAM,WAAW,CAAA;AAG5B,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAExD,IAAI,CAAC,uEAAuE,EAAE,GAAG,EAAE;IAC/E,MAAM,MAAM,GAAe;QACvB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACR,SAAS,EAAE;gBACP,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;aAChD;YACD,MAAM,EAAE;gBACJ,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;aAChD;YACD,OAAO,EAAE;gBACL,IAAI,EAAE,QAAQ;aACjB;SACJ;QACD,QAAQ,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAC;KAC/C,CAAA;IAED,MAAM,CAAC,KAAK,CACR,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,EACzB;;;;EAIN,CACG,CAAA;AACL,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;IACpD,MAAM,MAAM,GAAe;QACvB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACR,MAAM,EAAE;gBACJ,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;aAChD;SACJ;QACD,QAAQ,EAAE,EAAE;KACf,CAAA;IAED,MAAM,CAAC,KAAK,CACR,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,EACzB;;EAEN,CACG,CAAA;AACL,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,gDAAgD,EAAE,GAAG,EAAE;IACxD,MAAM,MAAM,GAAe;QACvB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACR,SAAS,EAAE;gBACP,IAAI,EAAE,QAAQ;aACjB;SACJ;QACD,QAAQ,EAAE,CAAC,WAAW,CAAC;KAC1B,CAAA;IAED,MAAM,CAAC,KAAK,CACR,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,EACzB;;EAEN,CACG,CAAA;AACL,CAAC,CAAC,CAAA"}
|
package/dist/run.d.ts
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Create a TerseAgent scoped to a job's skills and execute onTrigger.
|
|
5
|
-
* Tools are registered from the codegen factory on globalThis (needed because
|
|
6
|
-
* tsx may load a separate module instance of terse-sdk).
|
|
7
|
-
*/
|
|
8
|
-
export declare function executeJob(job: CreateJobParameters, event: SerializedEvent, options?: {
|
|
9
|
-
verbose?: boolean;
|
|
10
|
-
}): Promise<void>;
|
|
11
|
-
export declare function run(jobName?: string, eventJson?: string, eventFile?: string): Promise<void>;
|
|
1
|
+
import type { LanguageProvider } from "./providers/LanguageProvider.js";
|
|
2
|
+
export declare function run(jobName?: string, eventJson?: string, eventFile?: string, provider?: LanguageProvider, entryFile?: string): Promise<void>;
|
|
12
3
|
//# sourceMappingURL=run.d.ts.map
|
package/dist/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAA;AAGvE,wBAAsB,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAE,gBAAoC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8CrK"}
|
package/dist/run.js
CHANGED
|
@@ -1,58 +1,10 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
1
|
import chalk from "chalk";
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import { ApiRoutes, buildRoute, sdkRunTriggerEventResponseSchema, serializedEventSchema } from "terse-types";
|
|
4
|
+
import { fetchWithAuth, readApiKey } from "./api.js";
|
|
6
5
|
import { loadJob } from "./loadJob.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
import { BACKEND_URL } from "./config.js";
|
|
10
|
-
/**
|
|
11
|
-
* Create a TerseAgent scoped to a job's skills and execute onTrigger.
|
|
12
|
-
* Tools are registered from the codegen factory on globalThis (needed because
|
|
13
|
-
* tsx may load a separate module instance of terse-sdk).
|
|
14
|
-
*/
|
|
15
|
-
export async function executeJob(job, event, options) {
|
|
16
|
-
const inputEvent = convertSerializedEventToInputEvent(event);
|
|
17
|
-
const isVerbose = options?.verbose ?? false;
|
|
18
|
-
const apiKey = process.env.TERSE_API_KEY ?? null;
|
|
19
|
-
let sessionId;
|
|
20
|
-
let closeSession;
|
|
21
|
-
if (isVerbose && apiKey) {
|
|
22
|
-
const session = await openSessionStream(apiKey);
|
|
23
|
-
sessionId = session.sessionId;
|
|
24
|
-
closeSession = session.close;
|
|
25
|
-
}
|
|
26
|
-
const agent = new TerseAgent(job.skills, BACKEND_URL, sessionId);
|
|
27
|
-
const createTools = globalThis.__terse_createTools;
|
|
28
|
-
if (createTools) {
|
|
29
|
-
Object.defineProperty(agent, "tools", { value: createTools(agent) });
|
|
30
|
-
}
|
|
31
|
-
try {
|
|
32
|
-
if (job.filter) {
|
|
33
|
-
const shouldRun = await job.filter(inputEvent);
|
|
34
|
-
if (!shouldRun) {
|
|
35
|
-
console.log(chalk.dim(`\n Job "${job.name}" skipped (filter returned false).\n`));
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
if (isVerbose) {
|
|
40
|
-
console.log(chalk.cyan(` Job "${job.name}" started`));
|
|
41
|
-
}
|
|
42
|
-
await job.onTrigger(inputEvent, agent);
|
|
43
|
-
console.log(chalk.green(`\n Job "${job.name}" completed successfully.\n`));
|
|
44
|
-
}
|
|
45
|
-
catch (err) {
|
|
46
|
-
console.error(chalk.red(`\n Job "${job.name}" threw an error:\n`));
|
|
47
|
-
console.error(err);
|
|
48
|
-
process.exit(1);
|
|
49
|
-
}
|
|
50
|
-
finally {
|
|
51
|
-
closeSession?.();
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
export async function run(jobName, eventJson, eventFile) {
|
|
55
|
-
assertProjectRoot();
|
|
6
|
+
import { resolveProvider } from "./providers/resolveProvider.js";
|
|
7
|
+
export async function run(jobName, eventJson, eventFile, provider = resolveProvider(), entryFile) {
|
|
56
8
|
if (eventFile && !eventJson) {
|
|
57
9
|
try {
|
|
58
10
|
eventJson = fs.readFileSync(eventFile, "utf-8");
|
|
@@ -63,121 +15,58 @@ export async function run(jobName, eventJson, eventFile) {
|
|
|
63
15
|
process.exit(1);
|
|
64
16
|
}
|
|
65
17
|
}
|
|
66
|
-
|
|
18
|
+
readApiKey();
|
|
19
|
+
let rawEvent;
|
|
20
|
+
if (eventJson) {
|
|
21
|
+
try {
|
|
22
|
+
rawEvent = JSON.parse(eventJson);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
console.error(chalk.red("Error: --event must be valid JSON."));
|
|
26
|
+
console.error(chalk.dim(error instanceof Error ? error.message : String(error)));
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
rawEvent = await resolveEventFromRunId();
|
|
32
|
+
}
|
|
33
|
+
if (!rawEvent) {
|
|
67
34
|
console.error(chalk.red("Error: --event <json> or --event-file <path> is required.\n"));
|
|
68
|
-
console.error(chalk.dim(
|
|
35
|
+
console.error(chalk.dim(' Usage: terse run --event \'{"integrationType":"...","eventType":"...","formattedContent":"...","debugLog":"...","data":{...}}\''));
|
|
69
36
|
console.error(chalk.dim(" terse run --event-file ./event.json"));
|
|
70
37
|
console.error(chalk.dim(" Tip: Use `terse test` to interactively pick a sample event.\n"));
|
|
71
38
|
process.exit(1);
|
|
72
39
|
}
|
|
73
|
-
|
|
74
|
-
const { job } = await loadJob(jobName);
|
|
75
|
-
console.log(chalk.cyan(`\n Running job: ${job.name}\n`));
|
|
40
|
+
const { job } = await loadJob(provider, jobName, entryFile);
|
|
76
41
|
let parsed;
|
|
77
42
|
try {
|
|
78
|
-
parsed =
|
|
43
|
+
parsed = serializedEventSchema.parse(rawEvent);
|
|
79
44
|
}
|
|
80
|
-
catch {
|
|
81
|
-
console.error(chalk.red("Error: --event
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error(chalk.red("Error: --event does not match the canonical Trigger schema."));
|
|
47
|
+
console.error(chalk.dim(error instanceof Error ? error.message : String(error)));
|
|
82
48
|
process.exit(1);
|
|
83
49
|
}
|
|
84
|
-
await executeJob(job, parsed);
|
|
50
|
+
await provider.executeJob(job, parsed, { entryFile });
|
|
85
51
|
}
|
|
86
|
-
async function
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (!res.ok || !res.body) {
|
|
91
|
-
throw new Error(`Failed to open session event stream (HTTP ${res.status})`);
|
|
52
|
+
async function resolveEventFromRunId() {
|
|
53
|
+
const runId = process.env.TERSE_RUN_ID?.trim();
|
|
54
|
+
if (!runId) {
|
|
55
|
+
return undefined;
|
|
92
56
|
}
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
buffer = sessionId._remainingBuffer;
|
|
98
|
-
startEventConsumer(reader, decoder, buffer);
|
|
99
|
-
return {
|
|
100
|
-
sessionId: sessionId.value,
|
|
101
|
-
close: () => reader.cancel().catch(() => { })
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
async function readSessionId(reader, decoder, buffer) {
|
|
105
|
-
while (true) {
|
|
106
|
-
const { done, value } = await reader.read();
|
|
107
|
-
if (done)
|
|
108
|
-
throw new Error("Session stream ended before sending sessionId");
|
|
109
|
-
buffer += decoder.decode(value, { stream: true });
|
|
110
|
-
const lines = buffer.split("\n");
|
|
111
|
-
buffer = lines.pop() ?? "";
|
|
112
|
-
for (const line of lines) {
|
|
113
|
-
if (!line.startsWith("data: "))
|
|
114
|
-
continue;
|
|
115
|
-
const event = safeParseJson(line.slice(6));
|
|
116
|
-
if (event?.type === "session_started" && typeof event.sessionId === "string") {
|
|
117
|
-
return { value: event.sessionId, _remainingBuffer: buffer };
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
function startEventConsumer(reader, decoder, initialBuffer) {
|
|
123
|
-
let buffer = initialBuffer;
|
|
124
|
-
(async () => {
|
|
125
|
-
try {
|
|
126
|
-
while (true) {
|
|
127
|
-
const { done, value } = await reader.read();
|
|
128
|
-
if (done)
|
|
129
|
-
break;
|
|
130
|
-
buffer += decoder.decode(value, { stream: true });
|
|
131
|
-
const lines = buffer.split("\n");
|
|
132
|
-
buffer = lines.pop() ?? "";
|
|
133
|
-
for (const line of lines) {
|
|
134
|
-
if (!line.startsWith("data: "))
|
|
135
|
-
continue;
|
|
136
|
-
const event = safeParseJson(line.slice(6));
|
|
137
|
-
if (event)
|
|
138
|
-
logSessionEvent(event);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
catch {
|
|
143
|
-
// Stream cancelled by close() — expected
|
|
144
|
-
}
|
|
145
|
-
})();
|
|
146
|
-
}
|
|
147
|
-
function logSessionEvent(event) {
|
|
148
|
-
switch (event.type) {
|
|
149
|
-
case "tool_call_started":
|
|
150
|
-
console.log(chalk.blue(` [tool:start] ${event.toolCallStarted}`));
|
|
151
|
-
break;
|
|
152
|
-
case "tool_call_completed": {
|
|
153
|
-
const parsed = safeParseJson(event.toolCallCompleted);
|
|
154
|
-
const toolName = parsed?.tool || "unknown_tool";
|
|
155
|
-
const status = parsed?.status || "unknown";
|
|
156
|
-
const symbol = status === "completed" ? chalk.green("ok") : chalk.red("failed");
|
|
157
|
-
console.log(` [tool:done] ${toolName} (${symbol})`);
|
|
158
|
-
break;
|
|
159
|
-
}
|
|
160
|
-
case "action": {
|
|
161
|
-
const action = event.action;
|
|
162
|
-
const actionName = action?.action || "action";
|
|
163
|
-
const target = action?.target ? ` -> ${action.target}` : "";
|
|
164
|
-
console.log(chalk.magenta(` [action] ${actionName}${target}`));
|
|
165
|
-
break;
|
|
166
|
-
}
|
|
167
|
-
case "final_output":
|
|
168
|
-
console.log(chalk.green(`\n [final_output] ${event.finalOutput}\n`));
|
|
169
|
-
break;
|
|
170
|
-
case "error":
|
|
171
|
-
console.log(chalk.red(` [error] ${event.message}`));
|
|
172
|
-
break;
|
|
57
|
+
const apiKey = process.env.TERSE_API_KEY ?? null;
|
|
58
|
+
if (!apiKey) {
|
|
59
|
+
console.error(chalk.red(`Error: TERSE_RUN_ID is set but TERSE_API_KEY is missing, so the trigger event for run ${runId} cannot be fetched.`));
|
|
60
|
+
process.exit(1);
|
|
173
61
|
}
|
|
174
|
-
}
|
|
175
|
-
function safeParseJson(value) {
|
|
176
62
|
try {
|
|
177
|
-
|
|
63
|
+
const response = await fetchWithAuth(buildRoute(ApiRoutes.SDK.RUN_TRIGGER_EVENT, { runId }), apiKey);
|
|
64
|
+
return sdkRunTriggerEventResponseSchema.parse(response).event;
|
|
178
65
|
}
|
|
179
|
-
catch {
|
|
180
|
-
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error(chalk.red(`Error: Could not fetch the trigger event for run ${runId}.`));
|
|
68
|
+
console.error(chalk.dim(error instanceof Error ? error.message : String(error)));
|
|
69
|
+
process.exit(1);
|
|
181
70
|
}
|
|
182
71
|
}
|
|
183
72
|
//# sourceMappingURL=run.js.map
|
package/dist/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
|
package/dist/sampleEventId.d.ts
CHANGED
|
@@ -4,10 +4,6 @@ import type { SerializedEvent } from "terse-types";
|
|
|
4
4
|
* the underlying Trigger payload (`event.data`) is identical — we deliberately
|
|
5
5
|
* avoid hashing display strings like `formattedContent` because the server
|
|
6
6
|
* renders relative timestamps that drift between calls.
|
|
7
|
-
*
|
|
8
|
-
* For synthetic cron/webhook events the CLI builds in test.ts, the caller is
|
|
9
|
-
* responsible for ensuring each trigger produces a distinct `data` (e.g. by
|
|
10
|
-
* stamping a `_syntheticTriggerIndex`).
|
|
11
7
|
*/
|
|
12
8
|
export declare function hashEventKey(event: SerializedEvent): string;
|
|
13
9
|
//# sourceMappingURL=sampleEventId.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sampleEventId.d.ts","sourceRoot":"","sources":["../src/sampleEventId.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD
|
|
1
|
+
{"version":3,"file":"sampleEventId.d.ts","sourceRoot":"","sources":["../src/sampleEventId.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAO3D"}
|
package/dist/sampleEventId.js
CHANGED
|
@@ -4,10 +4,6 @@ import { createHash } from "node:crypto";
|
|
|
4
4
|
* the underlying Trigger payload (`event.data`) is identical — we deliberately
|
|
5
5
|
* avoid hashing display strings like `formattedContent` because the server
|
|
6
6
|
* renders relative timestamps that drift between calls.
|
|
7
|
-
*
|
|
8
|
-
* For synthetic cron/webhook events the CLI builds in test.ts, the caller is
|
|
9
|
-
* responsible for ensuring each trigger produces a distinct `data` (e.g. by
|
|
10
|
-
* stamping a `_syntheticTriggerIndex`).
|
|
11
7
|
*/
|
|
12
8
|
export function hashEventKey(event) {
|
|
13
9
|
const material = JSON.stringify({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sampleEventId.js","sourceRoot":"","sources":["../src/sampleEventId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAGxC
|
|
1
|
+
{"version":3,"file":"sampleEventId.js","sourceRoot":"","sources":["../src/sampleEventId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAGxC;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAsB;IAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5B,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;KACnB,CAAC,CAAA;IACF,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAC3E,CAAC"}
|
|
@@ -139,6 +139,9 @@ export declare const ApiRoutes: {
|
|
|
139
139
|
readonly INTEGRATIONS: "/workos-integration/integrations";
|
|
140
140
|
readonly WEBHOOK_SECRET: "/workos-integration/webhook-secret";
|
|
141
141
|
};
|
|
142
|
+
readonly SNOWFLAKE: {
|
|
143
|
+
readonly INTEGRATIONS: "/snowflake/integrations";
|
|
144
|
+
};
|
|
142
145
|
readonly ATTIO: {
|
|
143
146
|
readonly INTEGRATIONS: "/attio/integrations";
|
|
144
147
|
readonly OAUTH_CALLBACK: "/attio/oauth/callback";
|
|
@@ -245,8 +248,24 @@ export declare const ApiRoutes: {
|
|
|
245
248
|
readonly TOOL_EXECUTE: "/sdk/tool-execute";
|
|
246
249
|
readonly TOOL_DEFINITIONS: "/sdk/tool-definitions";
|
|
247
250
|
readonly AGENT_RUN: "/sdk/agent-run";
|
|
251
|
+
readonly APPROVAL_DECISION: "/sdk/approval-decision";
|
|
248
252
|
readonly SESSION_EVENTS: "/sdk/session-events";
|
|
249
253
|
readonly DEPLOY: "/sdk/deploy";
|
|
254
|
+
readonly DEVICE_TOKEN_EXCHANGE: "/sdk/auth/device-token-exchange";
|
|
255
|
+
readonly INTEGRATION_FIELDS: {
|
|
256
|
+
readonly pattern: "/sdk/integrations/:integrationType/fields";
|
|
257
|
+
readonly build: (integrationType: string) => string;
|
|
258
|
+
readonly params: {
|
|
259
|
+
readonly integrationType: "string";
|
|
260
|
+
};
|
|
261
|
+
};
|
|
262
|
+
readonly INTEGRATION_FORM_SUBMIT: {
|
|
263
|
+
readonly pattern: "/sdk/integrations/:integrationType/form-submit";
|
|
264
|
+
readonly build: (integrationType: string) => string;
|
|
265
|
+
readonly params: {
|
|
266
|
+
readonly integrationType: "string";
|
|
267
|
+
};
|
|
268
|
+
};
|
|
250
269
|
};
|
|
251
270
|
readonly NOTIFICATION_SETTINGS: "/notification-settings";
|
|
252
271
|
readonly SENT_NOTIFICATIONS: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiRoutes.d.ts","sourceRoot":"","sources":["../../src/shared/ApiRoutes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;6CAyBc,MAAM;;;;;;;;;;;;sCAcb,MAAM;;;;;;;oCAKR,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4CA0FE,MAAM;;;;;;;4CAKN,MAAM,cAAc,MAAM
|
|
1
|
+
{"version":3,"file":"ApiRoutes.d.ts","sourceRoot":"","sources":["../../src/shared/ApiRoutes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;6CAyBc,MAAM;;;;;;;;;;;;sCAcb,MAAM;;;;;;;oCAKR,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4CA0FE,MAAM;;;;;;;4CAKN,MAAM,cAAc,MAAM;;;;;;;;;;;;;;;;;;;;;;;4CA4B1B,MAAM;;;;;;;;;;;iCAWjB,MAAM;;;;;;;;;sCAQD,MAAM;;;;;;;sCAKN,MAAM,MAAM,MAAM;;;;;;;;sCAKlB,MAAM,MAAM,MAAM;;;;;;;;sCAKlB,MAAM,MAAM,MAAM;;;;;;;;sCAKlB,MAAM;;;;;;;;;;;;;;;;8CAoBE,MAAM;;;;;;;;;;;;iCAYnB,MAAM;;;;;;;;;;iCAUN,MAAM;;;;;;;;;;;;;;;;;;8CAkBO,MAAM;;;;;;;8CAKN,MAAM;;;;;;;;;;;;;;;;;;;wCAsBZ,MAAM;;;;;;;qCAKT,MAAM;;;;;;;sCAKL,MAAM;;;;;;;4CAKA,MAAM;;;;;;;;;sCASZ,MAAM;;;;;;;2CAKD,MAAM;;;;;;;;;;;;iCAchB,MAAM;;;;;;;;;wCASC,MAAM;;;;;;CAI3B,CAAA"}
|
package/dist/shared/ApiRoutes.js
CHANGED
|
@@ -145,6 +145,10 @@ export const ApiRoutes = {
|
|
|
145
145
|
INTEGRATIONS: "/workos-integration/integrations",
|
|
146
146
|
WEBHOOK_SECRET: "/workos-integration/webhook-secret"
|
|
147
147
|
},
|
|
148
|
+
// Snowflake routes
|
|
149
|
+
SNOWFLAKE: {
|
|
150
|
+
INTEGRATIONS: "/snowflake/integrations"
|
|
151
|
+
},
|
|
148
152
|
// Attio routes
|
|
149
153
|
ATTIO: {
|
|
150
154
|
INTEGRATIONS: "/attio/integrations",
|
|
@@ -236,8 +240,20 @@ export const ApiRoutes = {
|
|
|
236
240
|
TOOL_EXECUTE: "/sdk/tool-execute",
|
|
237
241
|
TOOL_DEFINITIONS: "/sdk/tool-definitions",
|
|
238
242
|
AGENT_RUN: "/sdk/agent-run",
|
|
243
|
+
APPROVAL_DECISION: "/sdk/approval-decision",
|
|
239
244
|
SESSION_EVENTS: "/sdk/session-events",
|
|
240
|
-
DEPLOY: "/sdk/deploy"
|
|
245
|
+
DEPLOY: "/sdk/deploy",
|
|
246
|
+
DEVICE_TOKEN_EXCHANGE: "/sdk/auth/device-token-exchange",
|
|
247
|
+
INTEGRATION_FIELDS: {
|
|
248
|
+
pattern: "/sdk/integrations/:integrationType/fields",
|
|
249
|
+
build: (integrationType) => `/sdk/integrations/${encodeURIComponent(integrationType)}/fields`,
|
|
250
|
+
params: { integrationType: "string" }
|
|
251
|
+
},
|
|
252
|
+
INTEGRATION_FORM_SUBMIT: {
|
|
253
|
+
pattern: "/sdk/integrations/:integrationType/form-submit",
|
|
254
|
+
build: (integrationType) => `/sdk/integrations/${encodeURIComponent(integrationType)}/form-submit`,
|
|
255
|
+
params: { integrationType: "string" }
|
|
256
|
+
}
|
|
241
257
|
},
|
|
242
258
|
NOTIFICATION_SETTINGS: "/notification-settings",
|
|
243
259
|
SENT_NOTIFICATIONS: {
|