@usenaive-sdk/blueprints 0.1.0 → 0.3.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/index.d.ts +199 -9
- package/dist/index.js +504 -163
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -80,6 +80,8 @@ declare const AppDeclSchema: z.ZodObject<{
|
|
|
80
80
|
mcp: z.ZodOptional<z.ZodString>;
|
|
81
81
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
82
82
|
from_env: z.ZodString;
|
|
83
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
84
|
+
generate: z.ZodLiteral<true>;
|
|
83
85
|
}, z.core.$strip>]>>>;
|
|
84
86
|
}, z.core.$strip>;
|
|
85
87
|
/**
|
|
@@ -146,6 +148,10 @@ declare const AgentDeclSchema: z.ZodObject<{
|
|
|
146
148
|
identity: z.ZodOptional<z.ZodString>;
|
|
147
149
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
148
150
|
}, z.core.$strip>>>;
|
|
151
|
+
intake: z.ZodOptional<z.ZodObject<{
|
|
152
|
+
message: z.ZodString;
|
|
153
|
+
budget_micro_usd: z.ZodOptional<z.ZodNumber>;
|
|
154
|
+
}, z.core.$strip>>;
|
|
149
155
|
}, z.core.$strip>;
|
|
150
156
|
/**
|
|
151
157
|
* A vault credential (§23) minus what `up` fills in. `value` is a real third-party secret, so it is
|
|
@@ -197,6 +203,21 @@ declare const ProjectSchema: z.ZodObject<{
|
|
|
197
203
|
name: z.ZodString;
|
|
198
204
|
blueprint: z.ZodOptional<z.ZodString>;
|
|
199
205
|
template: z.ZodOptional<z.ZodString>;
|
|
206
|
+
questions: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
207
|
+
type: z.ZodLiteral<"text">;
|
|
208
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
209
|
+
key: z.ZodString;
|
|
210
|
+
label: z.ZodString;
|
|
211
|
+
help: z.ZodOptional<z.ZodString>;
|
|
212
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
213
|
+
type: z.ZodLiteral<"choice">;
|
|
214
|
+
options: z.ZodArray<z.ZodString>;
|
|
215
|
+
multiple: z.ZodDefault<z.ZodBoolean>;
|
|
216
|
+
other: z.ZodDefault<z.ZodBoolean>;
|
|
217
|
+
key: z.ZodString;
|
|
218
|
+
label: z.ZodString;
|
|
219
|
+
help: z.ZodOptional<z.ZodString>;
|
|
220
|
+
}, z.core.$strip>], "type">>>;
|
|
200
221
|
skills: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
201
222
|
slug: z.ZodString;
|
|
202
223
|
file: z.ZodString;
|
|
@@ -233,6 +254,8 @@ declare const ProjectSchema: z.ZodObject<{
|
|
|
233
254
|
mcp: z.ZodOptional<z.ZodString>;
|
|
234
255
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
235
256
|
from_env: z.ZodString;
|
|
257
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
258
|
+
generate: z.ZodLiteral<true>;
|
|
236
259
|
}, z.core.$strip>]>>>;
|
|
237
260
|
}, z.core.$strip>>>;
|
|
238
261
|
agents: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
@@ -283,6 +306,10 @@ declare const ProjectSchema: z.ZodObject<{
|
|
|
283
306
|
identity: z.ZodOptional<z.ZodString>;
|
|
284
307
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
285
308
|
}, z.core.$strip>>>;
|
|
309
|
+
intake: z.ZodOptional<z.ZodObject<{
|
|
310
|
+
message: z.ZodString;
|
|
311
|
+
budget_micro_usd: z.ZodOptional<z.ZodNumber>;
|
|
312
|
+
}, z.core.$strip>>;
|
|
286
313
|
}, z.core.$strip>>>;
|
|
287
314
|
removed: z.ZodDefault<z.ZodObject<{
|
|
288
315
|
apps: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
@@ -343,6 +370,75 @@ type ConfigLoad = {
|
|
|
343
370
|
};
|
|
344
371
|
declare function loadConfig(dir: string): Promise<ConfigLoad>;
|
|
345
372
|
|
|
373
|
+
/**
|
|
374
|
+
* A built tree, from either place one can be. A **directory** is the apply a person runs: a
|
|
375
|
+
* checkout on their laptop or in CI. A **file map** is the apply the platform runs on their
|
|
376
|
+
* behalf — the tree comes out of a published artifact's object-store entry (`canonical-spec §31.1`)
|
|
377
|
+
* and there is no checkout anywhere, because a hosted run never clones a blueprint.
|
|
378
|
+
*/
|
|
379
|
+
type FileSource = string | Record<string, string>;
|
|
380
|
+
/**
|
|
381
|
+
* ONE FILTER, ONE DIGEST, BOTH SOURCES — which is the whole of why the map arm exists rather than
|
|
382
|
+
* the caller handing its map straight to `contentHash`.
|
|
383
|
+
*
|
|
384
|
+
* A published artifact's `content_hash` is compared against the newest deployment's to decide
|
|
385
|
+
* whether to upload at all (§31.1), and the two sides of that comparison are collected in different
|
|
386
|
+
* places: the deployment's from a directory here, the artifact's from a map on the server. If the
|
|
387
|
+
* map arm skipped one exclusion or one size cap, the digests would differ for two trees that ship
|
|
388
|
+
* the same bytes and every hosted install would re-upload, forever, with nothing to point at.
|
|
389
|
+
*/
|
|
390
|
+
declare function collectFiles(source: FileSource): Record<string, string>;
|
|
391
|
+
/**
|
|
392
|
+
* sha-256 over the files in path order, each as `path NUL byte-length NUL bytes`: the same tree
|
|
393
|
+
* hashes the same from any walk order, and the length prefix keeps two trees from sharing an
|
|
394
|
+
* encoding. Hex, so it travels as a plain string.
|
|
395
|
+
*/
|
|
396
|
+
declare function contentHash(files: Record<string, string>): string;
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* The blueprint install (`canonical-spec §29.6`) — one applied declaration per
|
|
400
|
+
* (organization, project), and the drift a `revision_conflict` names.
|
|
401
|
+
*
|
|
402
|
+
* `naive up` needed no server-side state while the only writer was a person with a clone: its
|
|
403
|
+
* working tree was the manifest. The studio applying the same declaration makes two writers on one
|
|
404
|
+
* organization, and neither can see the other. This row is what they share.
|
|
405
|
+
*
|
|
406
|
+
* It is not a second source of truth for what is provisioned — apps, agents, skills, identities and
|
|
407
|
+
* vaults stay keyed by name on their own routes. It records *that* an apply happened, with what, by
|
|
408
|
+
* whom, and against which revision.
|
|
409
|
+
*/
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* What one apply did to one resource. This is the vocabulary `naive up` has printed since it
|
|
413
|
+
* existed; it is written HERE, and imported by `@usenaive-sdk/blueprints`, for the reason
|
|
414
|
+
* `CLAUDE.md §2` gives: the hosted apply publishes the engine's report on the install (below), so
|
|
415
|
+
* it is a wire shape, and a wire shape has exactly one definition. The engine re-exports these two
|
|
416
|
+
* names unchanged, so nothing downstream of it learns a second word for the same thing.
|
|
417
|
+
*/
|
|
418
|
+
declare const ResourceActionSchema: z.ZodEnum<{
|
|
419
|
+
created: "created";
|
|
420
|
+
updated: "updated";
|
|
421
|
+
unchanged: "unchanged";
|
|
422
|
+
deleted: "deleted";
|
|
423
|
+
refused: "refused";
|
|
424
|
+
}>;
|
|
425
|
+
type ResourceAction = z.infer<typeof ResourceActionSchema>;
|
|
426
|
+
/** One line of an apply: what was named, what happened to it, and — for a refusal — why. */
|
|
427
|
+
declare const ResourceReportSchema: z.ZodObject<{
|
|
428
|
+
name: z.ZodString;
|
|
429
|
+
action: z.ZodEnum<{
|
|
430
|
+
created: "created";
|
|
431
|
+
updated: "updated";
|
|
432
|
+
unchanged: "unchanged";
|
|
433
|
+
deleted: "deleted";
|
|
434
|
+
refused: "refused";
|
|
435
|
+
}>;
|
|
436
|
+
id: z.ZodOptional<z.ZodString>;
|
|
437
|
+
url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
438
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
439
|
+
}, z.core.$strip>;
|
|
440
|
+
type ResourceReportLine = z.infer<typeof ResourceReportSchema>;
|
|
441
|
+
|
|
346
442
|
/**
|
|
347
443
|
* The report vocabulary `up` speaks (`workstreams/10-blueprints.md §2` item 4) and the handful of
|
|
348
444
|
* client-side moves every resource kind shares: one line per attempt with refusals caught into
|
|
@@ -350,14 +446,62 @@ declare function loadConfig(dir: string): Promise<ConfigLoad>;
|
|
|
350
446
|
* cursor pagination, and the by-name tombstone behind `removed`.
|
|
351
447
|
*/
|
|
352
448
|
|
|
353
|
-
type
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
449
|
+
type ResourceReport = ResourceReportLine;
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Apps in `naive up`: upsert by `GET /v1/apps?name=` (§29.2), `env` written as write-only secrets
|
|
453
|
+
* only when the live `value_hash` differs from the local one (ADR-0354, ADR-0357), and the
|
|
454
|
+
* `deploy_dir` shipped only when its content hash differs from the newest live deployment's
|
|
455
|
+
* (ADR-0357). Live secret names the config does not declare are reported, never deleted
|
|
456
|
+
* (ADR-0352). `mcp` is patched on drift, absent meaning `null` (§29.5); the platform mints the
|
|
457
|
+
* app's `VETTA_MCP_TOKEN` itself, so nothing here ever holds that token.
|
|
458
|
+
*
|
|
459
|
+
* A hosted apply also arrives with a PLATFORM ENVIRONMENT (`PlatformEnv`, §29.7) — the base URL, the
|
|
460
|
+
* identity the install runs as, and a scoped key it will mint for an app that asks. That layer is
|
|
461
|
+
* read before `{ from_env }`'s own environment, and a declaration may ask for a value nobody has
|
|
462
|
+
* with `{ generate: true }`. Both are provisioned ONCE per app, because a value the platform invents
|
|
463
|
+
* has no stable digest and rewriting it every apply would rotate a live credential.
|
|
464
|
+
*
|
|
465
|
+
* An app also records the project that made it (ADR-0375), and that stamp is compared before any
|
|
466
|
+
* write: a name this project does not own is refused rather than adopted, which is what standing
|
|
467
|
+
* up a second blueprint did to the first one's live deployment.
|
|
468
|
+
*/
|
|
469
|
+
|
|
470
|
+
/** The platform environment's variable names (`canonical-spec §29.7`) — fixed, never inferred. */
|
|
471
|
+
declare const PLATFORM_ENV: {
|
|
472
|
+
/** The base URL of the API this apply ran through. */
|
|
473
|
+
readonly api_url: "NAIVE_API_URL";
|
|
474
|
+
/** The identity the install runs as, when the declaration declares exactly one. */
|
|
475
|
+
readonly identity_id: "NAIVE_IDENTITY_ID";
|
|
476
|
+
/** A scoped organization API key minted for the app that asks for it. */
|
|
477
|
+
readonly api_key: "NAIVE_API_KEY";
|
|
478
|
+
};
|
|
479
|
+
/**
|
|
480
|
+
* WHAT THE PLATFORM PROVIDES A HOSTED APPLY, AND THE ONE DISTINCTION THAT MATTERS
|
|
481
|
+
* (`canonical-spec §29.7`).
|
|
482
|
+
*
|
|
483
|
+
* Absent on a laptop apply, which reads the author's shell and nothing else — the hosted path gains
|
|
484
|
+
* a layer, the local path does not lose one.
|
|
485
|
+
*
|
|
486
|
+
* **What the platform KNOWS it always tells the app; what the platform must INVENT it invents only
|
|
487
|
+
* on request, and only once.** That is not a stylistic split. A known value has a stable digest, so
|
|
488
|
+
* the `value_hash` compare that makes `naive up` idempotent (§29.2) can say `unchanged` about it and
|
|
489
|
+
* re-asserting it every apply costs nothing. An invented one never matches its own previous digest,
|
|
490
|
+
* so re-inventing it every apply would rotate a live credential under a build that still holds the
|
|
491
|
+
* old one — and, for a minted key, leave one dead `api_key` row behind per apply.
|
|
492
|
+
*/
|
|
493
|
+
interface PlatformEnv {
|
|
494
|
+
/**
|
|
495
|
+
* Values the platform knows. Written to every app this apply deploys that declares an `env` —
|
|
496
|
+
* whether or not the declaration names them, which is the `VETTA_MCP_TOKEN` precedent (§29.2) —
|
|
497
|
+
* and read FIRST by a `{ from_env }` that does name them.
|
|
498
|
+
*/
|
|
499
|
+
known: Record<string, string>;
|
|
500
|
+
/**
|
|
501
|
+
* Values the platform must invent, by variable name, given the app that asked. Called at most
|
|
502
|
+
* once per app, and only when that app holds no secret of that name.
|
|
503
|
+
*/
|
|
504
|
+
minted?: Record<string, (app: string) => Promise<string>>;
|
|
361
505
|
}
|
|
362
506
|
|
|
363
507
|
/**
|
|
@@ -370,6 +514,11 @@ interface ResourceReport {
|
|
|
370
514
|
* bounded exception — a declared agent's `schedules` are owned as a complete set (`agents.ts`).
|
|
371
515
|
* Skills and identities live here; apps, agents and vaults each have their own module, sharing the
|
|
372
516
|
* report vocabulary in `report.ts`.
|
|
517
|
+
*
|
|
518
|
+
* One thing here is not a reconcile: an agent this apply **created** that declares an `intake` is
|
|
519
|
+
* sent its briefing as a started session (`agents.ts`, `canonical-spec §31.4`). It is what turns a
|
|
520
|
+
* provisioned crew into a crew that has started working, and it is idempotent for the same reason
|
|
521
|
+
* everything else here is — the agent is created exactly once.
|
|
373
522
|
*/
|
|
374
523
|
|
|
375
524
|
interface UpReport {
|
|
@@ -385,6 +534,12 @@ interface UpReport {
|
|
|
385
534
|
agents: ResourceReport[];
|
|
386
535
|
/** One line per declared cron and per pruned live row, named `<agent> @ <cron>`. */
|
|
387
536
|
schedules: ResourceReport[];
|
|
537
|
+
/**
|
|
538
|
+
* One line per agent this apply **created** that declares an `intake` — the session that was
|
|
539
|
+
* started, named by the agent, `id` the `ses_`. Empty on every later apply of the same crew: an
|
|
540
|
+
* agent is created once, so it is briefed once (`agents.ts`).
|
|
541
|
+
*/
|
|
542
|
+
intake: ResourceReport[];
|
|
388
543
|
/**
|
|
389
544
|
* Live rows this client could not parse, named and stepped over (`report.ts`). One legacy row
|
|
390
545
|
* used to abort the whole apply before any write; it is now a line here and nothing else.
|
|
@@ -401,8 +556,43 @@ interface UpOptions {
|
|
|
401
556
|
* (ADR-0375). Off by default — adopting by default is what overwrote a live deployment.
|
|
402
557
|
*/
|
|
403
558
|
adopt?: boolean;
|
|
559
|
+
/**
|
|
560
|
+
* The built trees, by app name, for an apply that runs where there is no checkout: the platform
|
|
561
|
+
* applying a published artifact on an operator's behalf (`canonical-spec §31.1`). The bytes come
|
|
562
|
+
* out of the artifact's object-store entry, in the same file map `deploy_dir` would have been
|
|
563
|
+
* collected into — which is why `collectFiles` takes both and there is one digest (`files.ts`).
|
|
564
|
+
*
|
|
565
|
+
* Present ⇒ the disk is never read for an app, and an app whose tree is not in the map is refused
|
|
566
|
+
* by name rather than deployed empty. Absent ⇒ `dir` + `deploy_dir`, exactly as before.
|
|
567
|
+
*/
|
|
568
|
+
trees?: Record<string, Record<string, string>>;
|
|
569
|
+
/**
|
|
570
|
+
* Why a declared app is absent from `trees`, by app name — an object-store read that failed
|
|
571
|
+
* rather than an object that was never uploaded. Both come out of `builtTree` as one refusal;
|
|
572
|
+
* only the caller that did the reading can tell them apart, so only it can say (`apps.ts`).
|
|
573
|
+
*/
|
|
574
|
+
tree_errors?: Record<string, string>;
|
|
575
|
+
/**
|
|
576
|
+
* What an app's `{ from_env }` reads (`apps.ts`). The process's own environment by default —
|
|
577
|
+
* the author's shell, which is the whole point of `from_env` on a laptop. A hosted apply has no
|
|
578
|
+
* shell and passes the operator's **answers** instead (`canonical-spec §31.2`): the same
|
|
579
|
+
* declaration, resolved against the only environment that apply has.
|
|
580
|
+
*/
|
|
581
|
+
env?: Record<string, string | undefined>;
|
|
582
|
+
/**
|
|
583
|
+
* THE PLATFORM ENVIRONMENT (`canonical-spec §29.7`) — what the platform itself provides an app,
|
|
584
|
+
* read BEFORE `env` and written whether or not the declaration names it.
|
|
585
|
+
*
|
|
586
|
+
* Present only on a hosted apply, and that is the whole of the local/hosted difference: `naive up`
|
|
587
|
+
* from a checkout passes none, reads the author's shell, and behaves exactly as it always has.
|
|
588
|
+
*
|
|
589
|
+
* `NAIVE_IDENTITY_ID` is filled in here rather than by the caller, because the id does not exist
|
|
590
|
+
* until this run has created the identity — identities are upserted before apps for the same
|
|
591
|
+
* reason agents reference them by name.
|
|
592
|
+
*/
|
|
593
|
+
platform?: PlatformEnv;
|
|
404
594
|
}
|
|
405
595
|
/** Plan → apply → report. Every refusal is one line in the report, never a thrown escape. */
|
|
406
596
|
declare function up(config: Readonly<ProjectConfig>, client: VettaClient, opts?: UpOptions): Promise<UpReport>;
|
|
407
597
|
|
|
408
|
-
export { type AgentDecl, type AppDecl, BLUEPRINTS, BlueprintRefusal, CONFIG_CANDIDATES, type ConfigLoad, type CredentialDecl, type DefineInput, type IdentityDecl, type ProjectConfig, type ResourceAction, type ResourceReport, type ScheduleDecl, type SkillDecl, type Template, type TemplateChoice, type TemplateKind, type UpOptions, type UpReport, type VaultDecl, chooseTemplate, defineProject, loadConfig, parseProject, up };
|
|
598
|
+
export { type AgentDecl, type AppDecl, BLUEPRINTS, BlueprintRefusal, CONFIG_CANDIDATES, type ConfigLoad, type CredentialDecl, type DefineInput, type FileSource, type IdentityDecl, PLATFORM_ENV, type PlatformEnv, type ProjectConfig, type ResourceAction, type ResourceReport, type ScheduleDecl, type SkillDecl, type Template, type TemplateChoice, type TemplateKind, type UpOptions, type UpReport, type VaultDecl, chooseTemplate, collectFiles, contentHash, defineProject, loadConfig, parseProject, up };
|