import dedent from 'ts-dedent' import HighlightedCodeBlock, { HighlightedCodeBlockProps, } from '~/components/HighlightedCodeBlock' import { trpc } from '~/utils/trpc' import { useParams, useLocation, useNavigate } from 'react-router-dom' import Transition from '../Transition' import { useState } from 'react' import classNames from 'classnames' import { useMe } from '~/components/MeContext' import IVInputField from '~/components/IVInputField' import IVSelect from '~/components/IVSelect' import { examples } from '~/utils/examples' import IconCode from '~/icons/compiled/Code' function InstructionsContainer(props: { show?: boolean children: React.ReactNode }) { return (
{props.children}
) } function CompletionMessage() { return (

That's it! Once you start your app, this message will disappear and you'll be able to run the actions you're developing. Installation instructions and code samples will remain available{' '} in the docs .

) } function CodeSnippet(props: { children: React.ReactNode }) { return
{props.children}
} const codeBlockProps: Partial = { theme: 'light', className: 'bg-[#F6F8FA]', canDownload: false, } function InstallToExisting({ language }: { language: string }) { const key = trpc.useQuery(['key.dev']) const navigate = useNavigate() let mainCode = '' let mainFileName: string | undefined = undefined let actionCode: string | undefined = undefined let actionFileName: string | undefined = undefined switch (language) { case 'typescript': mainFileName = 'src/interval.ts' actionFileName = 'src/routes/hello_world.ts' mainCode = dedent(` import path from "path"; import { Interval } from "@interval/sdk"; const interval = new Interval({ apiKey: "${key?.data?.key || ''}", routesDirectory: path.resolve(__dirname, "routes"), }); interval.listen(); `) actionCode = dedent(` import { Action, io } from "@interval/sdk"; export default new Action(async () => { const name = await io.input.text("Your name"); return \`Hello, $\{name}\`; }); `) break case 'javascript': mainFileName = 'src/interval.js' actionFileName = 'src/routes/hello_world.js' mainCode = dedent(` const path = require("path"); const { Interval } = require("@interval/sdk"); const interval = new Interval({ apiKey: "${key?.data?.key || ''}", routesDirectory: path.resolve(__dirname, "routes"), }); interval.listen(); `) actionCode = dedent(` const { Action, io } = require("@interval/sdk"); module.exports = new Action(async () => { const name = await io.input.text("Your name"); return \`Hello, $\{name}\`; }); `) break case 'python': mainCode = dedent(` import os from interval_sdk import Interval, IO interval = Interval( "${key?.data?.key || ''}", ) @interval.action async def hello_world(io: IO): name = await io.input.text("Your name") return f"Hello {name}" interval.listen() `) break } return (

1. Install the SDK

You can also{' '} navigate(location.pathname, { state: 'installNew' }) } className="text-primary-500 font-medium hover:opacity-60 cursor-pointer" > create a new Interval project from a template .

2. Create your first action

Actions are created from within your codebase and will appear here when your SDK listener comes online. To create your first action, copy the following example code into your project:

{actionCode && ( )}
) } function LanguageTab({ label, isActive, onClick }) { return ( ) } function InstallToNew({ onboardingExampleSlug, language, }: { language: 'typescript' | 'javascript' | 'python' onboardingExampleSlug: string | null }) { const navigate = useNavigate() const key = trpc.useQuery(['key.dev']) const [selectedTemplate, setSelectedTemplate] = useState( onboardingExampleSlug || 'basic' ) const keyArg = key?.data ? `--personal_development_key=${key.data.key}` : '' const languageArg = `--language=${language}` const templateArg = `--template=${selectedTemplate}` const command = ['npx create-interval-app', templateArg, languageArg, keyArg] .join(' ') .replace(/\s+/g, ' ') const templateOptions = [ { label: 'Start from scratch', value: 'basic' }, ...examples.map(e => ({ label: e.label, value: e.id })), ] return (

1. Create a new Interval project

Generate the scaffolding for a blank slate Interval app, or select a template to start with{' '} one of our pre-built example tools .

{language === 'python' ? (

This command uses JavaScript command line tools to create the project from a template. If you don't have Node installed, you can{' '} navigate(location.pathname, { state: 'installExisting' }) } className="text-primary-500 font-medium hover:opacity-60 cursor-pointer" > add Interval to an existing codebase {' '} or{' '} clone the templates directly .

) : (

You can also{' '} navigate(location.pathname, { state: 'installExisting' }) } className="text-primary-500 font-medium hover:opacity-60 cursor-pointer" > add Interval to an existing codebase instead .

)} { setSelectedTemplate(e.target.value) }} options={templateOptions} defaultValue={selectedTemplate} />

2. Start your app

) } const onboardingScreens = ['installNew', 'installExisting'] export default function ConsoleOnboarding() { const location = useLocation() const { orgSlug } = useParams() const { me } = useMe() const onboardingExampleSlug = me?.userOrganizationAccess.find( uoa => uoa.organization.slug === orgSlug )?.onboardingExampleSlug let currentScreen = location.state ? location.state : 'installNew' if (!onboardingScreens.includes(String(currentScreen))) { currentScreen = 'installNew' } const [language, setLanguage] = useState< 'javascript' | 'typescript' | 'python' >('typescript') return (

Tools in Interval are called{' '} actions {' '} and created using the Interval SDK. Follow the steps below to install the SDK in your existing project and start building actions.

setLanguage('typescript')} /> setLanguage('javascript')} /> setLanguage('python')} />
{currentScreen === 'installNew' && ( )} {currentScreen === 'installExisting' && ( )}
) }