WEBVTT

1
00:00:00.000 --> 00:00:02.120
Hey guys, in this video I want to talk a

2
00:00:02.120 --> 00:00:04.340
bit about why Elements makes agents so productive

3
00:00:04.340 --> 00:00:06.200
and what it means to have a full stack.

4
00:00:07.160 --> 00:00:09.820
So an agent by itself is actually quite good at

5
00:00:09.820 --> 00:00:12.580
writing code and it's very good at applying

6
00:00:14.060 --> 00:00:19.040
different recipes and kind of different templates to problems.

7
00:00:19.300 --> 00:00:21.160
And so if you were going to build an application

8
00:00:21.160 --> 00:00:24.500
that had some database tables and you wanted

9
00:00:24.500 --> 00:00:27.200
to have let's say a real-time comment system or

10
00:00:27.200 --> 00:00:29.560
some other features, the agent can kind

11
00:00:29.560 --> 00:00:33.280
to stitch that together and figure it out, but it's

12
00:00:33.280 --> 00:00:34.700
going to have to reinvent a lot

13
00:00:34.700 --> 00:00:37.720
of things from scratch that wastes a lot of time and tokens.

14
00:00:38.640 --> 00:00:41.540
Conversely, or alternatively, it might have to go out and

15
00:00:41.540 --> 00:00:44.140
get a bunch of open source packages

16
00:00:44.140 --> 00:00:46.780
that it can try to use to stitch together to

17
00:00:46.780 --> 00:00:48.040
create your application.

18
00:00:48.760 --> 00:00:52.240
And those open source packages are often made by volunteers

19
00:00:52.240 --> 00:00:53.760
and are not necessarily

20
00:00:53.760 --> 00:00:54.940
made to work together.

21
00:00:54.940 --> 00:00:58.580
On top of that, there's no build tooling that tells

22
00:00:58.580 --> 00:01:00.100
the agent whether or not what it's

23
00:01:00.100 --> 00:01:01.480
doing is correct or not.

24
00:01:01.660 --> 00:01:04.740
And so it'll have to stitch or add on something like that.

25
00:01:05.620 --> 00:01:11.480
Elements creates an environment that's completely combined into one coherent tool system.

26
00:01:11.620 --> 00:01:13.840
So the agent can just focus on building your application,

27
00:01:14.060 --> 00:01:15.320
not stitching together building

28
00:01:15.320 --> 00:01:18.920
blocks or build server, things like that, that helps it make progress.

29
00:01:19.280 --> 00:01:20.980
So with the rest of the video, let me walk

30
00:01:20.980 --> 00:01:22.800
through some of those things that it has

31
00:01:22.800 --> 00:01:24.480
that makes the agent so productive.

32
00:01:25.440 --> 00:01:27.080
So first of all, when you create an Elements application,

33
00:01:27.280 --> 00:01:28.740
a server gets started in the

34
00:01:28.740 --> 00:01:29.560
background automatically.

35
00:01:30.220 --> 00:01:31.460
And that server is always running.

36
00:01:32.400 --> 00:01:35.240
That's actually, to my knowledge, the first build tool out

37
00:01:35.240 --> 00:01:36.420
there that works this way.

38
00:01:37.140 --> 00:01:40.220
And it's important because your agent, whether it's one agent

39
00:01:40.220 --> 00:01:41.560
or many agents, sometimes

40
00:01:41.560 --> 00:01:43.800
these days we're working with maybe 10, 20, as many

41
00:01:43.800 --> 00:01:44.960
agents as you want working on your

42
00:01:44.960 --> 00:01:48.580
app at once, can plug into the same server and

43
00:01:48.580 --> 00:01:51.840
get the same exact build results all

44
00:01:51.840 --> 00:01:55.120
at once, and your editor can plug into that same

45
00:01:55.120 --> 00:01:56.240
server as well.

46
00:01:56.520 --> 00:01:59.520
So typically, if you're pulling up Visual Studio Code, working

47
00:01:59.520 --> 00:02:00.320
in Vim, whatever you're

48
00:02:00.320 --> 00:02:04.340
working in, it would have its own TypeScript server, for

49
00:02:04.340 --> 00:02:06.540
instance, that's running separately

50
00:02:06.540 --> 00:02:07.700
from your build process.

51
00:02:07.920 --> 00:02:10.120
And then every agent that's working on your app would

52
00:02:10.120 --> 00:02:12.580
run its own type checker and its

53
00:02:12.580 --> 00:02:15.180
own build process, its own database migrations.

54
00:02:16.000 --> 00:02:17.740
None of them would be coordinating together.

55
00:02:17.740 --> 00:02:20.360
So you really need a project server, a central server

56
00:02:20.360 --> 00:02:22.880
that coordinates all of the things related

57
00:02:22.880 --> 00:02:23.980
to building your application.

58
00:02:24.260 --> 00:02:26.040
So that project server is always running.

59
00:02:26.660 --> 00:02:30.280
The second thing it has is TypeScript built into it.

60
00:02:30.900 --> 00:02:33.720
So we've actually brought in the TypeScript source code from

61
00:02:33.720 --> 00:02:35.200
Go into the Elements

62
00:02:35.200 --> 00:02:39.000
toolchain, and we've modified it somewhat to use our

63
00:02:39.000 --> 00:02:41.360
own source graph to make it multi-target

64
00:02:41.360 --> 00:02:44.960
so that it works with both server and browser targets.

65
00:02:44.960 --> 00:02:46.740
So we're going to type check your code for both

66
00:02:46.740 --> 00:02:47.840
the server and the browser.

67
00:02:48.580 --> 00:02:51.100
And we want it to make it extremely fast.

68
00:02:51.300 --> 00:02:54.720
And so it's significantly faster than just using the regular

69
00:02:54.720 --> 00:02:56.880
tsgo command line tool.

70
00:02:57.600 --> 00:03:00.680
And that's because we've overdone, we've overhauled the way

71
00:03:00.680 --> 00:03:02.620
that they do source graphs

72
00:03:02.620 --> 00:03:04.940
and the way that it gets its information comes from

73
00:03:04.940 --> 00:03:05.780
our project server.

74
00:03:06.000 --> 00:03:07.420
And we keep it up to date, we keep it

75
00:03:07.420 --> 00:03:09.060
in memory in real time.

76
00:03:09.660 --> 00:03:10.640
So we have type checking.

77
00:03:10.640 --> 00:03:16.020
When an agent asks for the type checking results, the

78
00:03:16.020 --> 00:03:17.740
type checking results have already been

79
00:03:17.740 --> 00:03:20.920
computed, and that's because as soon as you save a

80
00:03:20.920 --> 00:03:22.640
file, whether it's the agent saving the file or

81
00:03:22.640 --> 00:03:25.520
you're saving the file in your editor, the build happens

82
00:03:25.520 --> 00:03:27.300
automatically. Type checking happens as

83
00:03:27.300 --> 00:03:29.980
part of that build. Typically for a single file save,

84
00:03:30.120 --> 00:03:32.920
it might be one to five milliseconds just

85
00:03:32.920 --> 00:03:35.240
to do all of that, the entire build for both

86
00:03:35.240 --> 00:03:37.100
the server and the browser target. That includes

87
00:03:37.100 --> 00:03:38.780
There's type checking, program analysis,

88
00:03:39.500 --> 00:03:42.200
emitting, bundling, all the things that have to be done.

89
00:03:43.240 --> 00:03:45.000
And by the time the agent asked

90
00:03:45.000 --> 00:03:46.860
whether or not it made any mistakes,

91
00:03:47.420 --> 00:03:48.600
that work has been done.

92
00:03:48.700 --> 00:03:49.860
And so the result will come back

93
00:03:49.860 --> 00:03:52.540
in roughly 20 to 50 microseconds, very, very quick.

94
00:03:52.800 --> 00:03:55.900
So the project server is built such that

95
00:03:55.900 --> 00:03:59.120
it can respond almost in real time

96
00:03:59.120 --> 00:04:00.400
as the agent is working.

97
00:04:00.600 --> 00:04:02.360
And this empirically has shown us

98
00:04:02.360 --> 00:04:03.660
that it makes a big difference.

99
00:04:03.720 --> 00:04:05.820
So the agent can just keep working, working, working,

100
00:04:05.820 --> 00:04:08.620
working without doing a lot of follow-up work

101
00:04:08.620 --> 00:04:11.220
to see whether what it created is actually working.

102
00:04:12.200 --> 00:04:15.260
Okay, so the project server provides microsecond

103
00:04:15.260 --> 00:04:17.880
level feedback to the agent.

104
00:04:18.280 --> 00:04:19.540
This is also useful in your editor.

105
00:04:19.680 --> 00:04:20.600
If you're working in your editor,

106
00:04:21.320 --> 00:04:23.000
you might be used to seeing your TypeScript errors

107
00:04:23.000 --> 00:04:23.880
show up in your editor.

108
00:04:24.000 --> 00:04:25.360
You'll get that with Elements as well.

109
00:04:25.840 --> 00:04:28.140
But the project server is serving your editor

110
00:04:28.140 --> 00:04:30.560
and all the other, the tooling and the agents

111
00:04:30.560 --> 00:04:31.560
from the same place.

112
00:04:31.680 --> 00:04:34.460
So that'll save memory and CPU as well.

113
00:04:35.040 --> 00:04:38.600
Okay, so the project server then is providing type checking,

114
00:04:39.000 --> 00:04:40.600
program analysis, it's emitting

115
00:04:40.600 --> 00:04:41.520
all in real time.

116
00:04:42.080 --> 00:04:43.620
And then there's a bunch of tools that are built

117
00:04:43.620 --> 00:04:45.500
on top of that that the agent will use.

118
00:04:45.720 --> 00:04:47.860
So let's look at a typical feature that you're going

119
00:04:47.860 --> 00:04:48.920
to build in an application.

120
00:04:49.520 --> 00:04:52.560
Maybe it's a newsletter that you're trying to bring in-house.

121
00:04:52.720 --> 00:04:53.960
You want to build a paid newsletter.

122
00:04:54.720 --> 00:04:56.380
Well, you tell your agent you want to build a

123
00:04:56.380 --> 00:04:57.600
paid newsletter and the first thing it's

124
00:04:57.600 --> 00:04:59.660
going to have to do is to model some tables

125
00:04:59.660 --> 00:05:00.820
in the database.

126
00:05:01.200 --> 00:05:02.900
And to do that in Elements, it can do Elements,

127
00:05:03.020 --> 00:05:05.120
create migration, and that will create a migration

128
00:05:05.120 --> 00:05:07.480
file that it can then write in raw SQL, it

129
00:05:07.480 --> 00:05:10.880
doesn't need to use any ORM, or an abstraction

130
00:05:10.880 --> 00:05:12.460
in a framework, it just writes SQL.

131
00:05:12.720 --> 00:05:14.960
And agents are extremely good at writing SQL, there's a

132
00:05:14.960 --> 00:05:16.860
ton of training data for SQL.

133
00:05:17.660 --> 00:05:21.180
So it will write your migration in SQL, and that,

134
00:05:21.840 --> 00:05:25.260
once it's saved, will be synced automatically

135
00:05:25.260 --> 00:05:26.080
with your database.

136
00:05:26.080 --> 00:05:28.540
And so the agent doesn't have to do something like

137
00:05:28.540 --> 00:05:31.000
elements db migrate,

138
00:05:31.000 --> 00:05:32.460
like we used to have to do with Rails or

139
00:05:32.460 --> 00:05:34.100
some of the other frameworks that are out there

140
00:05:34.100 --> 00:05:36.700
And it doesn't have to add on another tool to

141
00:05:36.700 --> 00:05:37.700
do database migrations

142
00:05:37.700 --> 00:05:40.300
It's just baked in and it happens at the speed

143
00:05:40.300 --> 00:05:42.000
of file save while you're working

144
00:05:42.000 --> 00:05:44.300
if you want to change the migration you can just

145
00:05:44.300 --> 00:05:45.720
change it and it will patch the

146
00:05:46.280 --> 00:05:48.680
Database in real time. And so when you write a

147
00:05:48.680 --> 00:05:51.440
database migration, it might add 50 to 100 milliseconds to

148
00:05:51.440 --> 00:05:51.820
your build

149
00:05:51.820 --> 00:05:53.400
But it all happens in a blink of an eye

150
00:05:53.400 --> 00:05:55.060
you don't even really think about it.

151
00:05:55.260 --> 00:05:58.820
If there's any errors in the SQL, it will fail

152
00:05:58.820 --> 00:06:00.860
the build and the agent will find out

153
00:06:00.860 --> 00:06:01.640
about that right away.

154
00:06:01.840 --> 00:06:05.120
So database migration errors become part of the same build

155
00:06:05.120 --> 00:06:08.940
errors that are where you see

156
00:06:08.940 --> 00:06:11.880
type checking errors, program analysis errors, test errors, all of

157
00:06:11.880 --> 00:06:12.720
that comes back in the

158
00:06:12.720 --> 00:06:13.960
same report to the agent.

159
00:06:14.600 --> 00:06:17.440
So once it's done creating those database migrations, typically it

160
00:06:17.440 --> 00:06:18.100
would move on to

161
00:06:18.100 --> 00:06:22.080
creating some logic, some functions on the server that would

162
00:06:22.080 --> 00:06:23.500
access that database, either

163
00:06:23.500 --> 00:06:26.500
to pull data to load the page or perhaps to

164
00:06:26.500 --> 00:06:28.260
write a newsletter and to save it to your database.

165
00:06:29.520 --> 00:06:33.120
And typically frameworks have all kinds of abstractions to make

166
00:06:33.120 --> 00:06:34.680
this dance work effectively.

167
00:06:35.240 --> 00:06:38.140
We took multiple years to build this such that it's

168
00:06:38.140 --> 00:06:39.680
just completely seamless.

169
00:06:39.820 --> 00:06:43.820
We wanted the abstraction of calling something on the server

170
00:06:43.820 --> 00:06:45.840
to simply be you call a function.

171
00:06:45.840 --> 00:06:48.320
As humans, we're very good at calling functions.

172
00:06:48.540 --> 00:06:50.000
We learned that that's one of the first things we

173
00:06:50.000 --> 00:06:51.500
learn in programming is how to do that.

174
00:06:51.840 --> 00:06:54.200
It's obviously very easy for an agent to do that as well.

175
00:06:54.780 --> 00:06:56.440
And so you just write a function and you give

176
00:06:56.440 --> 00:06:59.080
it a special annotation that looks like a

177
00:06:59.080 --> 00:07:01.620
JSDoc comment that says @rpc.

178
00:07:01.860 --> 00:07:04.360
We call them build tags, but they look kind of

179
00:07:04.360 --> 00:07:06.080
like JSDoc tags.

180
00:07:06.420 --> 00:07:09.500
You say @rpc, and that marks the function as

181
00:07:09.500 --> 00:07:12.280
a remote procedure call or a function

182
00:07:12.280 --> 00:07:14.100
You can think of that can be invoked from the

183
00:07:14.100 --> 00:07:16.400
browser over the wire to the server.

184
00:07:16.900 --> 00:07:18.960
What's really cool about this is one is you really

185
00:07:18.960 --> 00:07:19.760
don't have to learn anything.

186
00:07:19.880 --> 00:07:22.040
We already know how to call functions and return values.

187
00:07:22.940 --> 00:07:26.040
It's secure automatically, so you don't have to worry about that.

188
00:07:27.200 --> 00:07:29.380
All the types of things that you might worry about

189
00:07:29.380 --> 00:07:32.260
with this have been thoroughly resolved.

190
00:07:32.480 --> 00:07:35.680
And so remote execution, things like that are not really

191
00:07:35.680 --> 00:07:36.500
an issue here.

192
00:07:36.840 --> 00:07:39.840
You just call the function with data as arguments,

193
00:07:39.840 --> 00:07:43.020
and you get data back over the wire, that's it.

194
00:07:43.700 --> 00:07:48.080
And so a function is just made by an RPC function

195
00:07:48.080 --> 00:07:49.900
by just putting a comment up at the top.

196
00:07:50.640 --> 00:07:52.220
So the agent can do this very, very quickly.

197
00:07:52.940 --> 00:07:56.580
Now, inside that function, you can call a SQL function,

198
00:07:56.980 --> 00:07:59.460
you can call the SQL function and just write raw SQL.

199
00:07:59.700 --> 00:08:01.080
And again, agents are really, really good

200
00:08:01.080 --> 00:08:02.180
at writing raw SQL.

201
00:08:02.880 --> 00:08:04.960
And when they call the SQL function,

202
00:08:05.040 --> 00:08:06.280
they type the SQL query,

203
00:08:06.720 --> 00:08:09.620
and they just don't even worry about SQL injection

204
00:08:09.620 --> 00:08:12.420
because our compiler takes care of that for it, so

205
00:08:12.420 --> 00:08:14.920
it just writes it as a plain template string,

206
00:08:15.060 --> 00:08:17.840
putting the parameters directly into the string, and then the

207
00:08:17.840 --> 00:08:19.420
compiler takes care of making sure

208
00:08:19.420 --> 00:08:21.580
that it's safe so that there can't be any injection.

209
00:08:22.280 --> 00:08:24.360
The compiler also does program analysis

210
00:08:24.360 --> 00:08:27.220
to make sure that the SQL is not called directly

211
00:08:27.220 --> 00:08:29.420
from the browser, so the browser has to go

212
00:08:29.420 --> 00:08:33.660
through one of these RPC functions in order to call

213
00:08:33.660 --> 00:08:35.860
SQL, otherwise it just simply won't compile.

214
00:08:36.800 --> 00:08:41.080
And then also inside of these RPC functions, we have

215
00:08:41.080 --> 00:08:43.740
a very simple primitive called session that the agent can

216
00:08:43.740 --> 00:08:46.900
work with to determine whether the user is authenticated or

217
00:08:46.900 --> 00:08:49.540
not, or to log in the user or log them

218
00:08:49.540 --> 00:08:49.820
out.

219
00:08:50.240 --> 00:08:52.620
And so it's some very simple primitives, maybe four or

220
00:08:52.620 --> 00:08:54.160
five primitives that the agent can work with.

221
00:08:54.220 --> 00:08:58.760
And from that, it can build all sorts of complicated backend logic.

222
00:08:59.560 --> 00:09:02.920
Now, the front end, the user interface, the agent needs

223
00:09:02.920 --> 00:09:04.580
to work with something that's

224
00:09:04.580 --> 00:09:10.000
reactive, a language that allows it to build complicated interfaces very quickly.

225
00:09:10.840 --> 00:09:11.920
And we want to build that.

226
00:09:12.060 --> 00:09:13.500
We built our own HTML language.

227
00:09:13.760 --> 00:09:16.340
It was many years in the making, and it actually

228
00:09:16.340 --> 00:09:17.920
started back in 2012.

229
00:09:18.620 --> 00:09:22.520
And the point of making that was to push down

230
00:09:22.520 --> 00:09:25.200
all the complexity of the reactivity

231
00:09:25.200 --> 00:09:28.360
and and getting things up to date away from the

232
00:09:28.360 --> 00:09:30.040
user and the syntax and down

233
00:09:30.040 --> 00:09:33.020
into the runtime. So when you're building these interfaces all

234
00:09:33.020 --> 00:09:33.560
you have to think

235
00:09:33.560 --> 00:09:36.980
about is the HTML markup. We didn't design a separate

236
00:09:36.980 --> 00:09:38.040
language we made it

237
00:09:38.040 --> 00:09:42.100
HTML completely with some light syntax extensions that allow you to do

238
00:09:42.100 --> 00:09:47.020
TypeScript expressions, constructor attributes, and so on. And then the data

239
00:09:47.020 --> 00:09:51.100
functions just like function parameters and they're made lexically scoped and

240
00:09:51.100 --> 00:09:52.200
automatically reactive.

241
00:09:53.080 --> 00:09:56.000
So the user interface will update automatically, our runtime will

242
00:09:56.000 --> 00:09:56.960
do that, and it does it as

243
00:09:56.960 --> 00:09:57.860
fast as possible.

244
00:09:58.040 --> 00:10:00.460
So the agent can move very, very fast to this

245
00:10:00.460 --> 00:10:02.080
because it already knows how to write HTML,

246
00:10:02.600 --> 00:10:05.460
it already knows how to do function parameters, and it

247
00:10:05.460 --> 00:10:07.140
just gets told don't worry about the

248
00:10:07.140 --> 00:10:07.980
data reactivity.

249
00:10:08.060 --> 00:10:09.200
That will just happen for you.

250
00:10:09.760 --> 00:10:13.340
And it can factor out the templates to create reusable

251
00:10:13.340 --> 00:10:14.700
templates really, really easily,

252
00:10:14.700 --> 00:10:15.980
and it will actually do that.

253
00:10:16.060 --> 00:10:18.060
So it makes your code more maintainable.

254
00:10:18.060 --> 00:10:22.200
It's fast to write, and it's very performant in the browser.

255
00:10:22.380 --> 00:10:24.760
The runtime takes care of making it performant.

256
00:10:25.480 --> 00:10:28.440
So now you have something that has, in the application

257
00:10:28.440 --> 00:10:29.760
framework, from the user interface

258
00:10:29.760 --> 00:10:33.440
to the backend functions to the database, it's all integrated

259
00:10:33.440 --> 00:10:34.820
to work together, and

260
00:10:34.820 --> 00:10:37.560
the agent can make ferocious forward progress.

261
00:10:37.960 --> 00:10:41.180
And the project server makes sure that it is not

262
00:10:41.180 --> 00:10:42.560
making any mistake, and it's giving

263
00:10:43.220 --> 00:10:46.080
it guidance on how to fix its mistakes, if it does.

264
00:10:46.580 --> 00:10:48.360
The final part of this is it's going to want

265
00:10:48.360 --> 00:10:49.240
to write some tests.

266
00:10:49.960 --> 00:10:52.280
Now, typically tests have been kind of a thorn in

267
00:10:52.280 --> 00:10:53.260
our side as developers,

268
00:10:53.420 --> 00:10:55.180
and people have different viewpoints on them.

269
00:10:56.400 --> 00:10:59.800
I personally like to write tests if it's a big

270
00:10:59.800 --> 00:11:02.480
application for things that could regress over time,

271
00:11:02.640 --> 00:11:04.920
and I also like to write tests if it helps

272
00:11:04.920 --> 00:11:05.920
me to build a feature.

273
00:11:06.460 --> 00:11:08.540
I don't overdo it, but I do think having tests,

274
00:11:08.720 --> 00:11:09.860
particularly if you're in a team

275
00:11:09.860 --> 00:11:12.760
or you're building a complicated system, you really do have

276
00:11:12.760 --> 00:11:13.420
to have tests.

277
00:11:13.420 --> 00:11:16.120
But historically, tests have been really slow.

278
00:11:16.840 --> 00:11:19.240
They're slow to run, they're kind of annoying to write.

279
00:11:19.560 --> 00:11:21.980
If you don't write them correctly, they can sometimes

280
00:11:21.980 --> 00:11:25.220
hose things up and slow down the development cycle.

281
00:11:25.880 --> 00:11:28.780
But I found that with agents, that has changed a lot.

282
00:11:29.440 --> 00:11:31.200
So agents really want to write tests.

283
00:11:31.640 --> 00:11:33.360
It's generally a good idea to write tests

284
00:11:33.360 --> 00:11:35.440
because it helps them to figure out whether they broke

285
00:11:35.440 --> 00:11:37.320
something that they built a couple of weeks ago

286
00:11:37.320 --> 00:11:38.300
or months or years ago.

287
00:11:38.380 --> 00:11:41.220
So it helps you to prevent regressions in your application.

288
00:11:41.220 --> 00:11:43.920
And what we need to do on the Elements side

289
00:11:43.920 --> 00:11:46.580
is to create a test runner that's extremely

290
00:11:46.580 --> 00:11:47.260
fast.

291
00:11:47.680 --> 00:11:52.340
It keeps the test results in memory, only reruns the

292
00:11:52.340 --> 00:11:53.980
test that have to be rerun based

293
00:11:53.980 --> 00:11:55.340
on the things that affect them.

294
00:11:55.880 --> 00:11:58.540
And when the agent asks for the test results, it

295
00:11:58.540 --> 00:12:00.820
gets those results in microseconds, just

296
00:12:00.820 --> 00:12:03.060
like type checking or any of the other build results

297
00:12:03.060 --> 00:12:03.680
that come back.

298
00:12:04.240 --> 00:12:07.160
So writing tests in Elements is extremely fast for the

299
00:12:07.160 --> 00:12:08.560
agent to do, and it also gets

300
00:12:08.560 --> 00:12:10.580
the results back extremely quickly.

301
00:12:11.340 --> 00:12:14.040
Next up, we have to get this code somehow to production.

302
00:12:14.260 --> 00:12:16.480
We have to deploy it onto a remote machine.

303
00:12:17.400 --> 00:12:20.060
And that's a lot of orchestration to do safely.

304
00:12:20.820 --> 00:12:22.740
And what we do with Elements is we take control

305
00:12:22.740 --> 00:12:23.440
of that process.

306
00:12:23.700 --> 00:12:26.760
We can work with any Ubuntu machine, any Linux Ubuntu machine.

307
00:12:26.800 --> 00:12:27.840
We provision the machine.

308
00:12:28.020 --> 00:12:28.980
We set it up automatically.

309
00:12:29.260 --> 00:12:31.140
We install whatever software needs to be installed.

310
00:12:31.840 --> 00:12:33.800
And once it's up and running, which usually takes about

311
00:12:33.800 --> 00:12:35.980
60 seconds the first time, a

312
00:12:35.980 --> 00:12:38.880
hot deploy will typically take anywhere from half a second

313
00:12:38.880 --> 00:12:40.780
to maybe five seconds on a slightly

314
00:12:40.780 --> 00:12:43.920
slower box. And the reason it's so fast is that

315
00:12:43.920 --> 00:12:46.320
we connect peer to peer, project server to project

316
00:12:46.320 --> 00:12:50.300
server. And if the build is failing locally, it won't

317
00:12:50.300 --> 00:12:52.600
even deploy at all. Once it connects for

318
00:12:52.600 --> 00:12:55.560
a deployment, it starts to run the deployment in sequence

319
00:12:55.560 --> 00:12:58.080
across one or as many machines as you

320
00:12:58.080 --> 00:12:59.880
have. You could have a cluster of five machines if

321
00:12:59.880 --> 00:13:02.160
you want. They're all load balanced automatically.

322
00:13:02.160 --> 00:13:05.540
SSL is done automatically, and the deployment will go through

323
00:13:05.540 --> 00:13:07.820
on each box the first part

324
00:13:07.820 --> 00:13:10.320
of the build, which is the type check, the program

325
00:13:10.320 --> 00:13:13.580
analysis, the basic compilation, and

326
00:13:13.580 --> 00:13:16.840
then it will run the database migrations, if there's any,

327
00:13:16.840 --> 00:13:18.700
to be run on the test database

328
00:13:18.700 --> 00:13:19.020
first.

329
00:13:19.160 --> 00:13:21.480
We always have a test database in addition to the

330
00:13:21.480 --> 00:13:23.120
app database for every single application,

331
00:13:23.340 --> 00:13:26.580
so your migration will be run on the test database.

332
00:13:26.880 --> 00:13:29.560
If they fail on the test database, the whole deploy stops.

333
00:13:29.560 --> 00:13:31.960
If they don't fail, we'll go ahead and run the

334
00:13:31.960 --> 00:13:35.940
tests and the tests run on only the test on

335
00:13:35.940 --> 00:13:36.280
the code

336
00:13:36.280 --> 00:13:39.180
that's in the build folder not your release and that's important because

337
00:13:39.180 --> 00:13:43.900
We're building up our way towards a safe release and

338
00:13:43.900 --> 00:13:46.300
your folder that's running and serving your applications

339
00:13:46.300 --> 00:13:49.980
Or serving your users is left alone until we're pretty

340
00:13:49.980 --> 00:13:51.740
sure that everything's going to be okay

341
00:13:51.740 --> 00:13:55.260
Pretty sure meaning we're almost a hundred percent sure

342
00:13:55.260 --> 00:13:59.140
Okay, so the tests run, now they run very quickly.

343
00:13:59.320 --> 00:14:01.680
We have up to four, five, eight,

344
00:14:01.880 --> 00:14:04.600
we can have as many test runners as we want,

345
00:14:04.780 --> 00:14:06.860
but typically we have as many as there are CPUs.

346
00:14:07.660 --> 00:14:09.660
And so there's gonna be tests running concurrently,

347
00:14:09.880 --> 00:14:10.920
takes a couple of milliseconds.

348
00:14:11.460 --> 00:14:14.260
If all of those pass, the database migrations

349
00:14:14.260 --> 00:14:16.480
will now run on your application server,

350
00:14:17.000 --> 00:14:18.360
or on your application database.

351
00:14:19.520 --> 00:14:24.220
And typically migrations run on your production app database

352
00:14:24.220 --> 00:14:25.600
in a couple of milliseconds.

353
00:14:26.400 --> 00:14:29.360
For ones that are longer, you can put up a maintenance page

354
00:14:29.360 --> 00:14:30.740
during that process if you want,

355
00:14:31.240 --> 00:14:34.100
but usually we don't do that for quick changes.

356
00:14:34.600 --> 00:14:36.180
By default, they'll run in a transaction,

357
00:14:36.500 --> 00:14:39.540
so if there's any errors, the whole thing will roll back

358
00:14:40.120 --> 00:14:40.900
for each migration.

359
00:14:41.360 --> 00:14:42.800
And once that's done and succeeded,

360
00:14:43.440 --> 00:14:46.300
we will flip the switch on the release

361
00:14:46.300 --> 00:14:49.600
that atomically does the final release,

362
00:14:49.600 --> 00:14:54.000
and then in memory hot reloads your server on Node

363
00:14:54.000 --> 00:14:56.440
.js and sends a signal to the browsers

364
00:14:56.440 --> 00:14:58.540
to hot reload themselves as well.

365
00:14:59.220 --> 00:15:01.040
Now the first time you do this, I guarantee you

366
00:15:01.040 --> 00:15:02.060
it will feel magical.

367
00:15:02.240 --> 00:15:04.500
If you're working with an agent, you can talk to

368
00:15:04.500 --> 00:15:06.180
the agent on your phone and you can

369
00:15:06.180 --> 00:15:08.400
say make this change to the home page and deploy it

370
00:15:08.400 --> 00:15:09.980
and boom, in a second or two later

371
00:15:09.980 --> 00:15:11.260
it's up on your phone.

372
00:15:11.960 --> 00:15:13.280
It's an incredible way to work.

373
00:15:14.260 --> 00:15:16.820
Having all of this together as a toolset that the

374
00:15:16.820 --> 00:15:18.820
agent can use to build applications

375
00:15:18.820 --> 00:15:20.520
is an absolute superpower.

376
00:15:21.320 --> 00:15:23.160
And once you get used to working this way,

377
00:15:23.560 --> 00:15:26.360
I don't think you'll ever want to go back to anything again.

378
00:15:27.600 --> 00:15:29.400
Everything from being able to build the feature

379
00:15:29.400 --> 00:15:31.700
to deploying it and having it in production

380
00:15:32.380 --> 00:15:35.200
is completely integrated tightly to work well together.

381
00:15:35.980 --> 00:15:39.480
And so you can really safely build very complex applications

382
00:15:39.480 --> 00:15:42.080
from the prototype where you're just building something quickly

383
00:15:42.080 --> 00:15:45.400
in a couple of hours to just continuing to build with it

384
00:15:45.400 --> 00:15:47.340
from days to weeks to months and years

385
00:15:47.340 --> 00:15:51.380
on the same exact code base across many different agent sessions.

386
00:15:52.340 --> 00:15:55.140
And I think you can feel much, much more confident

387
00:15:55.140 --> 00:15:56.520
that you're going to have an application

388
00:15:56.520 --> 00:16:00.800
that's maintainable and built the correct way, because Elements provides the guardrails,

389
00:16:01.160 --> 00:16:04.180
the project server, and the framework to make it all consistent.

390
00:16:04.820 --> 00:16:06.820
So I hope this gives you a better sense of

391
00:16:06.820 --> 00:16:10.260
how Elements helps guide agents, makes it

392
00:16:10.260 --> 00:16:13.000
a kind of superpower for agents to be super productive,

393
00:16:13.580 --> 00:16:14.720
but I think it's also great

394
00:16:14.720 --> 00:16:15.340
for humans.

395
00:16:15.340 --> 00:16:17.380
And so if you, for whatever reason, are just using

396
00:16:17.380 --> 00:16:19.000
agents occasionally, or if you want

397
00:16:19.000 --> 00:16:21.280
to get in there and write the code yourself, you

398
00:16:21.280 --> 00:16:22.420
can also do that.

399
00:16:22.700 --> 00:16:24.520
So you can feel safe that even if you let

400
00:16:24.520 --> 00:16:26.660
agents run loose for a couple of months, and

401
00:16:26.660 --> 00:16:28.460
then you say, hey, I want a human team to

402
00:16:28.460 --> 00:16:30.260
come in and work on this for a bit, you can

403
00:16:30.260 --> 00:16:32.940
just hand it off, and it will be a good,

404
00:16:32.980 --> 00:16:34.080
maintainable code base.

405
00:16:34.600 --> 00:16:35.860
All right, let me know if you've got any questions

406
00:16:35.860 --> 00:16:36.540
in the comments.
