@gram-ai/create-function 0.4.0 → 0.5.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/main.js +21 -9
- package/dist/main.js.map +1 -1
- package/gram-template-gram/CHANGELOG.md +12 -0
- package/gram-template-gram/NEXT_STEPS.txt +1 -1
- package/gram-template-gram/README.md +4 -8
- package/gram-template-gram/node_modules/.bin/mcp-inspector +21 -0
- package/gram-template-gram/package.json +4 -4
- package/gram-template-gram/src/gram.ts +3 -1
- package/gram-template-gram/src/server.ts +119 -38
- package/package.json +2 -2
- package/src/main.ts +23 -9
package/dist/main.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { parse } from "@bomb.sh/args";
|
|
2
|
+
import { isCancel, log, taskLog } from "@clack/prompts";
|
|
1
3
|
import { existsSync } from "node:fs";
|
|
2
4
|
import fs from "node:fs/promises";
|
|
3
5
|
import { join, resolve } from "node:path";
|
|
4
6
|
import process from "node:process";
|
|
5
7
|
import { $ } from "zx";
|
|
6
|
-
import { isCancel, log, taskLog } from "@clack/prompts";
|
|
7
|
-
import { parse } from "@bomb.sh/args";
|
|
8
8
|
import pkg from "../package.json" with { type: "json" };
|
|
9
9
|
import { confirmOrClack, selectOrClack, textOrClack, yn, } from "./prompts/helpers.js";
|
|
10
10
|
const packageNameRE = /^(@?[a-z0-9-_]+\/)?[a-z0-9-_]+$/;
|
|
@@ -15,12 +15,13 @@ Usage:
|
|
|
15
15
|
${packageManager} create @gram-ai/function [options]
|
|
16
16
|
|
|
17
17
|
Options:
|
|
18
|
-
--template <name>
|
|
19
|
-
--name <name>
|
|
20
|
-
--dir <path>
|
|
21
|
-
--git <yes|no>
|
|
22
|
-
--install <yes|no>
|
|
23
|
-
-
|
|
18
|
+
--template <name> Template to use (gram, mcp)
|
|
19
|
+
--name <name> Project name
|
|
20
|
+
--dir <path> Directory to create project in
|
|
21
|
+
--git <yes|no> Initialize git repository
|
|
22
|
+
--install <yes|no> Install dependencies
|
|
23
|
+
--install-cli <yes|no> Install the Gram CLI
|
|
24
|
+
-y, --yes Skip all prompts and use defaults
|
|
24
25
|
|
|
25
26
|
Examples:
|
|
26
27
|
${packageManager} create @gram-ai/function
|
|
@@ -36,7 +37,7 @@ async function init(argv) {
|
|
|
36
37
|
}
|
|
37
38
|
const args = parse(argv, {
|
|
38
39
|
alias: { y: "yes", h: "help" },
|
|
39
|
-
string: ["template", "name", "dir", "git", "install"],
|
|
40
|
+
string: ["template", "name", "dir", "git", "install", "installCli"],
|
|
40
41
|
boolean: ["yes", "help"],
|
|
41
42
|
});
|
|
42
43
|
if (args.help) {
|
|
@@ -118,6 +119,13 @@ async function init(argv) {
|
|
|
118
119
|
log.info("Operation cancelled.");
|
|
119
120
|
return;
|
|
120
121
|
}
|
|
122
|
+
const installCli = await confirmOrClack({
|
|
123
|
+
message: "Install the Gram CLI? Required to deploy tools to Gram.",
|
|
124
|
+
})(args.yes || yn(args.installCli ?? false));
|
|
125
|
+
if (isCancel(installCli)) {
|
|
126
|
+
log.info("Operation cancelled.");
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
121
129
|
const tlog = taskLog({
|
|
122
130
|
title: "Setting up project",
|
|
123
131
|
});
|
|
@@ -183,6 +191,10 @@ async function init(argv) {
|
|
|
183
191
|
tlog.message(`Installing dependencies with ${packageManager}`);
|
|
184
192
|
await $ `cd ${dir} && ${packageManager} install`;
|
|
185
193
|
}
|
|
194
|
+
if (installCli) {
|
|
195
|
+
tlog.message("Installing Gram CLI");
|
|
196
|
+
await $ `which gram || (curl -fsSL https://go.getgram.ai/cli.sh | bash; gram auth)`;
|
|
197
|
+
}
|
|
186
198
|
let successMessage = `All done! Run \`cd ${dir} && ${packageManager} run build\` to build your first Gram Function.`;
|
|
187
199
|
successMessage = await fs
|
|
188
200
|
.readFile(join(templateDir, "NEXT_STEPS.txt"), "utf-8")
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# gram-template-gram
|
|
2
|
+
|
|
3
|
+
## 0.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5ea5fcd: Reverted the Gram Functions TS framework template to export the instance of
|
|
8
|
+
`Gram` as the default export in `src/gram.ts`. This makes the boilerplate code
|
|
9
|
+
work again when deployed.
|
|
10
|
+
- Updated dependencies [5ea5fcd]
|
|
11
|
+
- Updated dependencies [15cbf7e]
|
|
12
|
+
- @gram-ai/functions@0.5.1
|
|
@@ -2,7 +2,7 @@ All done! Jump in with `cd $DIR`.
|
|
|
2
2
|
|
|
3
3
|
Some next steps:
|
|
4
4
|
|
|
5
|
-
-
|
|
5
|
+
- Start a local development MCP server with `$PACKAGE_MANAGER run dev`
|
|
6
6
|
|
|
7
7
|
- Build your function with `$PACKAGE_MANAGER run build`
|
|
8
8
|
|
|
@@ -40,20 +40,16 @@ pnpm build
|
|
|
40
40
|
## Testing Locally
|
|
41
41
|
|
|
42
42
|
If you want to poke at the tools you've built during local development, you can
|
|
43
|
-
start a
|
|
43
|
+
start a local MCP server over stdio transport with:
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
pnpm dev
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Specifically, this command will spin up [MCP inspector][mcp-inspector] to let
|
|
50
|
+
you interactively test your tools.
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
curl \
|
|
53
|
-
--data '{"name": "greet", "input": {"name": "Georges"}}' \
|
|
54
|
-
-H "Content-Type: application/json" \
|
|
55
|
-
http://localhost:3000/tool-call
|
|
56
|
-
```
|
|
52
|
+
[mcp-inspector]: https://github.com/modelcontextprotocol/inspector
|
|
57
53
|
|
|
58
54
|
## What next?
|
|
59
55
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
+
|
|
4
|
+
case `uname` in
|
|
5
|
+
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
+
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
+
basedir=`cygpath -w "$basedir"`
|
|
8
|
+
fi
|
|
9
|
+
;;
|
|
10
|
+
esac
|
|
11
|
+
|
|
12
|
+
if [ -z "$NODE_PATH" ]; then
|
|
13
|
+
export NODE_PATH="/home/runner/work/gram/gram/node_modules/.pnpm/@modelcontextprotocol+inspector@0.17.1_@types+node@22.18.6_@types+react-dom@19.1.9_@typ_cc52197392af7d7a50d2088d86700a7d/node_modules/@modelcontextprotocol/inspector/cli/build/node_modules:/home/runner/work/gram/gram/node_modules/.pnpm/@modelcontextprotocol+inspector@0.17.1_@types+node@22.18.6_@types+react-dom@19.1.9_@typ_cc52197392af7d7a50d2088d86700a7d/node_modules/@modelcontextprotocol/inspector/cli/node_modules:/home/runner/work/gram/gram/node_modules/.pnpm/@modelcontextprotocol+inspector@0.17.1_@types+node@22.18.6_@types+react-dom@19.1.9_@typ_cc52197392af7d7a50d2088d86700a7d/node_modules/@modelcontextprotocol/inspector/node_modules:/home/runner/work/gram/gram/node_modules/.pnpm/@modelcontextprotocol+inspector@0.17.1_@types+node@22.18.6_@types+react-dom@19.1.9_@typ_cc52197392af7d7a50d2088d86700a7d/node_modules/@modelcontextprotocol/node_modules:/home/runner/work/gram/gram/node_modules/.pnpm/@modelcontextprotocol+inspector@0.17.1_@types+node@22.18.6_@types+react-dom@19.1.9_@typ_cc52197392af7d7a50d2088d86700a7d/node_modules:/home/runner/work/gram/gram/node_modules/.pnpm/node_modules"
|
|
14
|
+
else
|
|
15
|
+
export NODE_PATH="/home/runner/work/gram/gram/node_modules/.pnpm/@modelcontextprotocol+inspector@0.17.1_@types+node@22.18.6_@types+react-dom@19.1.9_@typ_cc52197392af7d7a50d2088d86700a7d/node_modules/@modelcontextprotocol/inspector/cli/build/node_modules:/home/runner/work/gram/gram/node_modules/.pnpm/@modelcontextprotocol+inspector@0.17.1_@types+node@22.18.6_@types+react-dom@19.1.9_@typ_cc52197392af7d7a50d2088d86700a7d/node_modules/@modelcontextprotocol/inspector/cli/node_modules:/home/runner/work/gram/gram/node_modules/.pnpm/@modelcontextprotocol+inspector@0.17.1_@types+node@22.18.6_@types+react-dom@19.1.9_@typ_cc52197392af7d7a50d2088d86700a7d/node_modules/@modelcontextprotocol/inspector/node_modules:/home/runner/work/gram/gram/node_modules/.pnpm/@modelcontextprotocol+inspector@0.17.1_@types+node@22.18.6_@types+react-dom@19.1.9_@typ_cc52197392af7d7a50d2088d86700a7d/node_modules/@modelcontextprotocol/node_modules:/home/runner/work/gram/gram/node_modules/.pnpm/@modelcontextprotocol+inspector@0.17.1_@types+node@22.18.6_@types+react-dom@19.1.9_@typ_cc52197392af7d7a50d2088d86700a7d/node_modules:/home/runner/work/gram/gram/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
+
fi
|
|
17
|
+
if [ -x "$basedir/node" ]; then
|
|
18
|
+
exec "$basedir/node" "$basedir/../@modelcontextprotocol/inspector/cli/build/cli.js" "$@"
|
|
19
|
+
else
|
|
20
|
+
exec node "$basedir/../@modelcontextprotocol/inspector/cli/build/cli.js" "$@"
|
|
21
|
+
fi
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "gram-template-gram",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.1",
|
|
5
5
|
"author": "",
|
|
6
6
|
"description": "",
|
|
7
7
|
"private": true,
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"node": ">=22.18.0"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
|
-
"dev": "node ./src/server.ts",
|
|
22
|
+
"dev": "mcp-inspector node ./src/server.ts",
|
|
23
23
|
"lint": "tsc --noEmit",
|
|
24
24
|
"build": "node -e \"console.log('Stubbed out')\"",
|
|
25
25
|
"_:build": "gram-build",
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@gram-ai/functions": "workspace:",
|
|
31
|
+
"@modelcontextprotocol/sdk": "^1.20.1",
|
|
31
32
|
"zod": "^4"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
|
-
"@
|
|
35
|
+
"@modelcontextprotocol/inspector": "^0.17.1",
|
|
35
36
|
"@types/node": "22.x",
|
|
36
|
-
"hono": "^4",
|
|
37
37
|
"typescript": "^5"
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Gram } from "@gram-ai/functions";
|
|
2
2
|
import * as z from "zod/mini";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const gram = new Gram().tool({
|
|
5
5
|
name: "greet",
|
|
6
6
|
description: "Greet someone special",
|
|
7
7
|
inputSchema: { name: z.string() },
|
|
@@ -9,3 +9,5 @@ export const gram = new Gram().tool({
|
|
|
9
9
|
return ctx.json({ message: `Hello, ${input.name}!` });
|
|
10
10
|
},
|
|
11
11
|
});
|
|
12
|
+
|
|
13
|
+
export default gram;
|
|
@@ -1,44 +1,125 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
1
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
|
+
import {
|
|
3
|
+
CallToolRequestSchema,
|
|
4
|
+
ListToolsRequestSchema,
|
|
5
|
+
type CallToolResult,
|
|
6
|
+
type ListToolsResult,
|
|
7
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
8
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
9
|
+
|
|
10
|
+
import pkg from "../package.json" with { type: "json" };
|
|
11
|
+
import gram from "./gram.ts";
|
|
12
|
+
|
|
13
|
+
const structuredLike = /\b(yaml|yml|json|toml|xml|xhtml)\b/i;
|
|
14
|
+
const textLike = /^text\//i;
|
|
15
|
+
const imageLike = /^image\//i;
|
|
16
|
+
const audioLike = /^audio\//i;
|
|
17
|
+
|
|
18
|
+
export const server = new Server(
|
|
19
|
+
{
|
|
20
|
+
name: pkg.name,
|
|
21
|
+
version: pkg.version,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
capabilities: {
|
|
25
|
+
tools: {},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
server.setRequestHandler(
|
|
31
|
+
ListToolsRequestSchema,
|
|
32
|
+
async (): Promise<ListToolsResult> => {
|
|
33
|
+
const tools = gram.manifest().tools.map((t) => {
|
|
34
|
+
return {
|
|
35
|
+
name: t.name,
|
|
36
|
+
description: t.description,
|
|
37
|
+
inputSchema: t.inputSchema,
|
|
38
|
+
};
|
|
39
|
+
}) as ListToolsResult["tools"];
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
tools,
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
server.setRequestHandler(
|
|
48
|
+
CallToolRequestSchema,
|
|
49
|
+
async (req, extra): Promise<CallToolResult> => {
|
|
50
|
+
const { name, arguments: args } = req.params;
|
|
51
|
+
|
|
52
|
+
const resp = await gram.handleToolCall({ name, input: args } as any, {
|
|
53
|
+
signal: extra.signal,
|
|
34
54
|
});
|
|
55
|
+
|
|
56
|
+
let ctype = resp.headers.get("Content-Type") || "";
|
|
57
|
+
ctype = ctype.split(";")[0]?.trim() || "";
|
|
58
|
+
|
|
59
|
+
switch (true) {
|
|
60
|
+
case textLike.test(ctype) || structuredLike.test(ctype): {
|
|
61
|
+
const text = await resp.text();
|
|
62
|
+
return {
|
|
63
|
+
content: [{ type: "text", text }],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
case imageLike.test(ctype): {
|
|
67
|
+
return {
|
|
68
|
+
content: [
|
|
69
|
+
{
|
|
70
|
+
type: "image",
|
|
71
|
+
mimeType: ctype,
|
|
72
|
+
data: await responseToBase64(resp),
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
case audioLike.test(ctype): {
|
|
78
|
+
return {
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: "audio",
|
|
82
|
+
mimeType: ctype,
|
|
83
|
+
data: await responseToBase64(resp),
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
default: {
|
|
89
|
+
return {
|
|
90
|
+
isError: true,
|
|
91
|
+
content: [
|
|
92
|
+
{
|
|
93
|
+
type: "text",
|
|
94
|
+
text: `Unhandled content type: ${ctype}. Create a handler for this type in the MCP server.`,
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
async function responseToBase64(resp: Response): Promise<string> {
|
|
104
|
+
const blob = await resp.arrayBuffer();
|
|
105
|
+
const buffer = Buffer.from(blob);
|
|
106
|
+
return buffer.toString("base64");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function run() {
|
|
110
|
+
console.error("Starting MCP server with stdio...");
|
|
111
|
+
const stdio = new StdioServerTransport();
|
|
112
|
+
await server.connect(stdio);
|
|
113
|
+
|
|
114
|
+
const quit = async () => {
|
|
115
|
+
console.error("\nShutting down MCP server...");
|
|
116
|
+
await server.close();
|
|
117
|
+
process.exit(0);
|
|
35
118
|
};
|
|
36
|
-
process.
|
|
37
|
-
process.
|
|
119
|
+
process.once("SIGINT", quit);
|
|
120
|
+
process.once("SIGTERM", quit);
|
|
38
121
|
}
|
|
39
122
|
|
|
40
123
|
if (import.meta.main) {
|
|
41
|
-
|
|
124
|
+
run();
|
|
42
125
|
}
|
|
43
|
-
|
|
44
|
-
export default app;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gram-ai/create-function",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.1",
|
|
5
5
|
"description": "Build AI tools and deploy them to getgram.ai",
|
|
6
6
|
"keywords": [],
|
|
7
7
|
"homepage": "https://github.com/speakeasy-api/gram",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"prettier": "^3.6.2",
|
|
39
39
|
"typescript": "5.9.2",
|
|
40
40
|
"zod": "^3.25.76",
|
|
41
|
-
"@gram-ai/functions": "^0.
|
|
41
|
+
"@gram-ai/functions": "^0.5.1"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build": "tsc --noEmit false"
|
package/src/main.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { parse } from "@bomb.sh/args";
|
|
2
|
+
import { isCancel, log, taskLog } from "@clack/prompts";
|
|
1
3
|
import { existsSync } from "node:fs";
|
|
2
4
|
import fs from "node:fs/promises";
|
|
3
5
|
import { join, resolve } from "node:path";
|
|
4
6
|
import process from "node:process";
|
|
5
7
|
import { $ } from "zx";
|
|
6
|
-
import { isCancel, log, taskLog } from "@clack/prompts";
|
|
7
|
-
import { parse } from "@bomb.sh/args";
|
|
8
8
|
import pkg from "../package.json" with { type: "json" };
|
|
9
9
|
|
|
10
10
|
import {
|
|
@@ -24,12 +24,13 @@ Usage:
|
|
|
24
24
|
${packageManager} create @gram-ai/function [options]
|
|
25
25
|
|
|
26
26
|
Options:
|
|
27
|
-
--template <name>
|
|
28
|
-
--name <name>
|
|
29
|
-
--dir <path>
|
|
30
|
-
--git <yes|no>
|
|
31
|
-
--install <yes|no>
|
|
32
|
-
-
|
|
27
|
+
--template <name> Template to use (gram, mcp)
|
|
28
|
+
--name <name> Project name
|
|
29
|
+
--dir <path> Directory to create project in
|
|
30
|
+
--git <yes|no> Initialize git repository
|
|
31
|
+
--install <yes|no> Install dependencies
|
|
32
|
+
--install-cli <yes|no> Install the Gram CLI
|
|
33
|
+
-y, --yes Skip all prompts and use defaults
|
|
33
34
|
|
|
34
35
|
Examples:
|
|
35
36
|
${packageManager} create @gram-ai/function
|
|
@@ -47,7 +48,7 @@ async function init(argv: string[]): Promise<void> {
|
|
|
47
48
|
|
|
48
49
|
const args = parse(argv, {
|
|
49
50
|
alias: { y: "yes", h: "help" },
|
|
50
|
-
string: ["template", "name", "dir", "git", "install"],
|
|
51
|
+
string: ["template", "name", "dir", "git", "install", "installCli"],
|
|
51
52
|
boolean: ["yes", "help"],
|
|
52
53
|
});
|
|
53
54
|
|
|
@@ -138,6 +139,14 @@ async function init(argv: string[]): Promise<void> {
|
|
|
138
139
|
return;
|
|
139
140
|
}
|
|
140
141
|
|
|
142
|
+
const installCli = await confirmOrClack({
|
|
143
|
+
message: "Install the Gram CLI? Required to deploy tools to Gram.",
|
|
144
|
+
})(args.yes || yn(args.installCli ?? false));
|
|
145
|
+
if (isCancel(installCli)) {
|
|
146
|
+
log.info("Operation cancelled.");
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
141
150
|
const tlog = taskLog({
|
|
142
151
|
title: "Setting up project",
|
|
143
152
|
});
|
|
@@ -217,6 +226,11 @@ async function init(argv: string[]): Promise<void> {
|
|
|
217
226
|
await $`cd ${dir} && ${packageManager} install`;
|
|
218
227
|
}
|
|
219
228
|
|
|
229
|
+
if (installCli) {
|
|
230
|
+
tlog.message("Installing Gram CLI");
|
|
231
|
+
await $`which gram || (curl -fsSL https://go.getgram.ai/cli.sh | bash; gram auth)`;
|
|
232
|
+
}
|
|
233
|
+
|
|
220
234
|
let successMessage = `All done! Run \`cd ${dir} && ${packageManager} run build\` to build your first Gram Function.`;
|
|
221
235
|
successMessage = await fs
|
|
222
236
|
.readFile(join(templateDir, "NEXT_STEPS.txt"), "utf-8")
|