@gram-ai/create-function 0.1.0 → 0.2.0

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 CHANGED
@@ -9,6 +9,25 @@ 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-_]+$/;
11
11
  const knownPackageManagers = new Set(["npm", "yarn", "pnpm", "bun", "deno"]);
12
+ function printUsage(packageManager) {
13
+ console.log(`
14
+ Usage:
15
+ ${packageManager} create @gram-ai/function [options]
16
+
17
+ Options:
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
+ -y, --yes Skip all prompts and use defaults
24
+
25
+ Examples:
26
+ ${packageManager} create @gram-ai/function
27
+ ${packageManager} create @gram-ai/function --template mcp --name ecommerce
28
+ ${packageManager} create @gram-ai/function --yes --template gram
29
+ `);
30
+ }
12
31
  async function init(argv) {
13
32
  let packageManager = "npm";
14
33
  let detectedPM = process.env["npm_config_user_agent"]?.split("/")[0] || "";
@@ -16,10 +35,14 @@ async function init(argv) {
16
35
  packageManager = detectedPM;
17
36
  }
18
37
  const args = parse(argv, {
19
- alias: { y: "yes" },
38
+ alias: { y: "yes", h: "help" },
20
39
  string: ["template", "name", "dir", "git", "install"],
21
- boolean: ["yes"],
40
+ boolean: ["yes", "help"],
22
41
  });
42
+ if (args.help) {
43
+ printUsage(packageManager);
44
+ return;
45
+ }
23
46
  const template = await selectOrClack({
24
47
  message: "Pick a framework",
25
48
  options: [
@@ -98,14 +121,19 @@ async function init(argv) {
98
121
  const tlog = taskLog({
99
122
  title: "Setting up project",
100
123
  });
124
+ const isLocalDev = yn(process.env["GRAM_DEV"]);
101
125
  tlog.message("Scaffolding");
102
126
  const dirname = import.meta.dirname;
103
127
  const templateDir = resolve(join(dirname, "..", `gram-template-${template}`));
104
128
  await fs.cp(templateDir, dir, {
105
129
  recursive: true,
106
- filter: (src) => !src.includes("node_modules") &&
107
- !src.includes(".git") &&
108
- !src.includes("dist"),
130
+ filter: (src) => {
131
+ let banned = src.includes(".git") || src.includes("NEXT_STEPS.txt");
132
+ if (isLocalDev) {
133
+ banned ||= src.includes("node_modules") || src.includes("dist");
134
+ }
135
+ return !banned;
136
+ },
109
137
  });
110
138
  let gramFuncsVersion = pkg.devDependencies["@gram-ai/functions"];
111
139
  if (gramFuncsVersion == null || gramFuncsVersion.startsWith("workspace:")) {
@@ -113,8 +141,7 @@ async function init(argv) {
113
141
  // lockstep so we can just use the matching version.
114
142
  gramFuncsVersion = `^${pkg.version}`;
115
143
  }
116
- if (yn(process.env["GRAM_DEV"]) &&
117
- existsSync(resolve(dirname, "..", "..", "functions"))) {
144
+ if (isLocalDev && existsSync(resolve(dirname, "..", "..", "functions"))) {
118
145
  // For local development, use the local version of `@gram-ai/functions`
119
146
  // if it exists.
120
147
  const localPkgPath = resolve(dirname, "..", "..", "functions");
@@ -144,7 +171,14 @@ async function init(argv) {
144
171
  tlog.message(`Installing dependencies with ${packageManager}`);
145
172
  await $ `cd ${dir} && ${packageManager} install`;
146
173
  }
147
- tlog.success(`All done! Run \`cd ${dir} && ${packageManager} run build\` to build your first Gram Function.`);
174
+ let successMessage = `All done! Run \`cd ${dir} && ${packageManager} run build\` to build your first Gram Function.`;
175
+ successMessage = await fs
176
+ .readFile(join(templateDir, "NEXT_STEPS.txt"), "utf-8")
177
+ .catch(() => successMessage);
178
+ successMessage = successMessage
179
+ .replaceAll("$PACKAGE_MANAGER", packageManager)
180
+ .replaceAll("$DIR", dir);
181
+ tlog.success(successMessage);
148
182
  }
149
183
  try {
150
184
  await init(process.argv);
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ All done! Jump in with `cd $DIR`.
2
+
3
+ Some next steps:
4
+
5
+ - Build your function with `$PACKAGE_MANAGER run build` and deploy it with the Gram CLI: https://www.speakeasy.com/docs/gram/command-line/installation.
6
+
7
+ - Run the provided Hono server to simulate tool calls over HTTP with `$PACKAGE_MANAGER run dev` and:
8
+
9
+ curl \
10
+ --data '{"name": "greet", "input": {"name": "Friend"}}' \
11
+ -H "Content-Type: application/json" \
12
+ http://localhost:3000/tool-call
13
+
14
+ Have fun 🚀
@@ -0,0 +1,58 @@
1
+ # Hello from Gram Functions!
2
+
3
+ This project builds and deploys [Gram Functions](https://getgram.ai) using a
4
+ tiny TypeScript framework that looks like this:
5
+
6
+ ```ts
7
+ import { Gram } from "@gram-ai/functions";
8
+ import * as z from "zod/mini";
9
+
10
+ const gram = new Gram().tool({
11
+ name: "greet",
12
+ description: "Greet someone special",
13
+ inputSchema: { name: z.string() },
14
+ async execute(ctx, input) {
15
+ return ctx.json({ message: `Hello, ${input.name}!` });
16
+ },
17
+ });
18
+
19
+ export default gram;
20
+ ```
21
+
22
+ Gram Functions are tools for LLMs and MCP servers that can do arbitrary tasks
23
+ such as fetching data from APIs, performing calculations, or interacting with
24
+ hosted databases.
25
+
26
+ ## Getting Started
27
+
28
+ To get started, install dependencies and run the development server:
29
+
30
+ ```bash
31
+ pnpm install
32
+ ```
33
+
34
+ To build a zip file that can be deployed to Gram, run:
35
+
36
+ ```bash
37
+ pnpm build
38
+ ```
39
+
40
+ If you want to poke at the tools you've built during local development, you can
41
+ start a Hono server with:
42
+
43
+ ```bash
44
+ pnpm dev
45
+ ```
46
+
47
+ Now you can simulate tool calls with:
48
+
49
+ ```bash
50
+ curl \
51
+ --data '{"name": "greet", "input": {"name": "Georges"}}' \
52
+ -H "Content-Type: application/json" \
53
+ http://localhost:3000/tool-call
54
+ ```
55
+
56
+ ## What next?
57
+
58
+ To learn more about using the framework, check out [CONTRIBUTING.md](./CONTRIBUTING.md)
@@ -19,6 +19,7 @@
19
19
  "node": ">=22.18.0"
20
20
  },
21
21
  "scripts": {
22
+ "dev": "node ./src/server.ts",
22
23
  "lint": "tsc --noEmit",
23
24
  "build": "node ./src/build.ts",
24
25
  "prebuild": "tsc -p tsconfig.json",
@@ -29,7 +30,9 @@
29
30
  "zod": "^4"
30
31
  },
31
32
  "devDependencies": {
32
- "typescript": "^5",
33
- "@types/node": "22.x"
33
+ "@hono/node-server": "^1.19.5",
34
+ "@types/node": "22.x",
35
+ "hono": "^4",
36
+ "typescript": "^5"
34
37
  }
35
38
  }
@@ -0,0 +1,44 @@
1
+ import { serve } from "@hono/node-server";
2
+ import { Hono } from "hono";
3
+ import gram from "./functions.ts";
4
+
5
+ const app = new Hono();
6
+
7
+ app.post("/tool-call", async (c) => {
8
+ const req = await c.req.json();
9
+ return await gram.handleToolCall(req, {
10
+ signal: AbortSignal.timeout(1 * 60 * 1000),
11
+ });
12
+ });
13
+
14
+ app.get("/manifest", async () => {
15
+ const manifest = gram.manifest();
16
+ return new Response(JSON.stringify(manifest, null, 2), {
17
+ headers: { "Content-Type": "application/json" },
18
+ });
19
+ });
20
+
21
+ export function startServer(port: number = 3000) {
22
+ const server = serve({ fetch: app.fetch, port }, (info) => {
23
+ console.log(`Listening on http://localhost:${info.port}`);
24
+ });
25
+
26
+ const onClose = () => {
27
+ console.log("Shutting down server...");
28
+ server.close((err) => {
29
+ if (err) {
30
+ console.error(err);
31
+ process.exit(1);
32
+ }
33
+ process.exit(0);
34
+ });
35
+ };
36
+ process.on("SIGINT", onClose);
37
+ process.on("SIGTERM", onClose);
38
+ }
39
+
40
+ if (import.meta.main) {
41
+ startServer();
42
+ }
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.1.0",
4
+ "version": "0.2.0",
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.1.0"
41
+ "@gram-ai/functions": "^0.2.0"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "tsc --noEmit false"
package/src/main.ts CHANGED
@@ -18,6 +18,26 @@ const packageNameRE = /^(@?[a-z0-9-_]+\/)?[a-z0-9-_]+$/;
18
18
 
19
19
  const knownPackageManagers = new Set(["npm", "yarn", "pnpm", "bun", "deno"]);
20
20
 
21
+ function printUsage(packageManager: string): void {
22
+ console.log(`
23
+ Usage:
24
+ ${packageManager} create @gram-ai/function [options]
25
+
26
+ Options:
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
+ -y, --yes Skip all prompts and use defaults
33
+
34
+ Examples:
35
+ ${packageManager} create @gram-ai/function
36
+ ${packageManager} create @gram-ai/function --template mcp --name ecommerce
37
+ ${packageManager} create @gram-ai/function --yes --template gram
38
+ `);
39
+ }
40
+
21
41
  async function init(argv: string[]): Promise<void> {
22
42
  let packageManager = "npm";
23
43
  let detectedPM = process.env["npm_config_user_agent"]?.split("/")[0] || "";
@@ -26,11 +46,16 @@ async function init(argv: string[]): Promise<void> {
26
46
  }
27
47
 
28
48
  const args = parse(argv, {
29
- alias: { y: "yes" },
49
+ alias: { y: "yes", h: "help" },
30
50
  string: ["template", "name", "dir", "git", "install"],
31
- boolean: ["yes"],
51
+ boolean: ["yes", "help"],
32
52
  });
33
53
 
54
+ if (args.help) {
55
+ printUsage(packageManager);
56
+ return;
57
+ }
58
+
34
59
  const template = await selectOrClack<string>({
35
60
  message: "Pick a framework",
36
61
  options: [
@@ -117,15 +142,20 @@ async function init(argv: string[]): Promise<void> {
117
142
  title: "Setting up project",
118
143
  });
119
144
 
145
+ const isLocalDev = yn(process.env["GRAM_DEV"]);
146
+
120
147
  tlog.message("Scaffolding");
121
148
  const dirname = import.meta.dirname;
122
149
  const templateDir = resolve(join(dirname, "..", `gram-template-${template}`));
123
150
  await fs.cp(templateDir, dir, {
124
151
  recursive: true,
125
- filter: (src) =>
126
- !src.includes("node_modules") &&
127
- !src.includes(".git") &&
128
- !src.includes("dist"),
152
+ filter: (src) => {
153
+ let banned = src.includes(".git") || src.includes("NEXT_STEPS.txt");
154
+ if (isLocalDev) {
155
+ banned ||= src.includes("node_modules") || src.includes("dist");
156
+ }
157
+ return !banned;
158
+ },
129
159
  });
130
160
 
131
161
  let gramFuncsVersion = pkg.devDependencies["@gram-ai/functions"];
@@ -134,10 +164,7 @@ async function init(argv: string[]): Promise<void> {
134
164
  // lockstep so we can just use the matching version.
135
165
  gramFuncsVersion = `^${pkg.version}`;
136
166
  }
137
- if (
138
- yn(process.env["GRAM_DEV"]) &&
139
- existsSync(resolve(dirname, "..", "..", "functions"))
140
- ) {
167
+ if (isLocalDev && existsSync(resolve(dirname, "..", "..", "functions"))) {
141
168
  // For local development, use the local version of `@gram-ai/functions`
142
169
  // if it exists.
143
170
  const localPkgPath = resolve(dirname, "..", "..", "functions");
@@ -176,9 +203,15 @@ async function init(argv: string[]): Promise<void> {
176
203
  await $`cd ${dir} && ${packageManager} install`;
177
204
  }
178
205
 
179
- tlog.success(
180
- `All done! Run \`cd ${dir} && ${packageManager} run build\` to build your first Gram Function.`,
181
- );
206
+ let successMessage = `All done! Run \`cd ${dir} && ${packageManager} run build\` to build your first Gram Function.`;
207
+ successMessage = await fs
208
+ .readFile(join(templateDir, "NEXT_STEPS.txt"), "utf-8")
209
+ .catch(() => successMessage);
210
+ successMessage = successMessage
211
+ .replaceAll("$PACKAGE_MANAGER", packageManager)
212
+ .replaceAll("$DIR", dir);
213
+
214
+ tlog.success(successMessage);
182
215
  }
183
216
 
184
217
  try {