create-cogitator-app 0.4.0 → 0.5.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/lib.d.ts CHANGED
@@ -1,127 +1,839 @@
1
- type Template = 'basic' | 'memory' | 'swarm' | 'workflow' | 'api-server' | 'nextjs';
2
- type LLMProvider = 'ollama' | 'openai' | 'anthropic' | 'google';
3
- type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun';
4
- interface ProjectOptions {
1
+ import { z } from 'zod';
2
+ import { ModelRegistry, ModelInfo } from '@cogitator-ai/models';
3
+
4
+ declare const PROVIDERS: readonly ["ollama", "openai", "anthropic", "google"];
5
+ declare const APP_KINDS: readonly ["script", "server", "next", "channels", "worker"];
6
+ declare const SERVERS: readonly ["express", "fastify", "hono", "koa", "tetsu"];
7
+ declare const MEMORIES: readonly ["none", "memory", "sqlite", "postgres", "redis", "mongodb"];
8
+ declare const VECTOR_STORES: readonly ["memory", "postgres", "qdrant"];
9
+ declare const FEATURES: readonly ["harness", "mcp", "rag", "workflows", "durable", "swarms", "evals", "otel", "langfuse", "voice", "sandbox", "a2a"];
10
+ declare const DEPLOY_TARGETS: readonly ["none", "docker", "fly"];
11
+ declare const CODING_AGENTS: readonly ["claude", "cursor", "codex"];
12
+ declare const PACKAGE_MANAGERS: readonly ["pnpm", "npm", "yarn", "bun"];
13
+ declare const CHANNELS: readonly ["telegram", "discord", "slack", "webchat"];
14
+ type LLMProvider = (typeof PROVIDERS)[number];
15
+ type AppKind = (typeof APP_KINDS)[number];
16
+ type ServerFramework = (typeof SERVERS)[number];
17
+ type MemoryKind = (typeof MEMORIES)[number];
18
+ type VectorStore = (typeof VECTOR_STORES)[number];
19
+ type FeatureId = (typeof FEATURES)[number];
20
+ type DeployTarget = (typeof DEPLOY_TARGETS)[number];
21
+ type CodingAgent = (typeof CODING_AGENTS)[number];
22
+ type PackageManager = (typeof PACKAGE_MANAGERS)[number];
23
+ type ChannelKind = (typeof CHANNELS)[number];
24
+ /**
25
+ * Why `name` cannot be the generated package's name, or `undefined` when it can.
26
+ * The name lands in package.json and in generated code, so it has to be a valid
27
+ * unscoped npm package name.
28
+ */
29
+ declare function validateProjectName(name: string): string | undefined;
30
+ /**
31
+ * Everything that decides what a generated project contains. A spec is plain data:
32
+ * it is stored in the project's package.json (`cogitator.spec`) so the project can
33
+ * be regenerated and extended with `cogitator add`, and it never holds secrets.
34
+ */
35
+ declare const ProjectSpecSchema: z.ZodObject<{
36
+ name: z.ZodString;
37
+ preset: z.ZodOptional<z.ZodString>;
38
+ app: z.ZodEnum<{
39
+ script: "script";
40
+ server: "server";
41
+ next: "next";
42
+ channels: "channels";
43
+ worker: "worker";
44
+ }>;
45
+ server: z.ZodOptional<z.ZodEnum<{
46
+ express: "express";
47
+ fastify: "fastify";
48
+ hono: "hono";
49
+ koa: "koa";
50
+ tetsu: "tetsu";
51
+ }>>;
52
+ channels: z.ZodDefault<z.ZodArray<z.ZodEnum<{
53
+ telegram: "telegram";
54
+ discord: "discord";
55
+ slack: "slack";
56
+ webchat: "webchat";
57
+ }>>>;
58
+ memory: z.ZodEnum<{
59
+ none: "none";
60
+ memory: "memory";
61
+ sqlite: "sqlite";
62
+ postgres: "postgres";
63
+ redis: "redis";
64
+ mongodb: "mongodb";
65
+ }>;
66
+ vectorStore: z.ZodDefault<z.ZodEnum<{
67
+ memory: "memory";
68
+ postgres: "postgres";
69
+ qdrant: "qdrant";
70
+ }>>;
71
+ features: z.ZodDefault<z.ZodArray<z.ZodEnum<{
72
+ harness: "harness";
73
+ mcp: "mcp";
74
+ rag: "rag";
75
+ workflows: "workflows";
76
+ durable: "durable";
77
+ swarms: "swarms";
78
+ evals: "evals";
79
+ otel: "otel";
80
+ langfuse: "langfuse";
81
+ voice: "voice";
82
+ sandbox: "sandbox";
83
+ a2a: "a2a";
84
+ }>>>;
85
+ provider: z.ZodEnum<{
86
+ ollama: "ollama";
87
+ openai: "openai";
88
+ anthropic: "anthropic";
89
+ google: "google";
90
+ }>;
91
+ model: z.ZodString;
92
+ deploy: z.ZodDefault<z.ZodEnum<{
93
+ none: "none";
94
+ docker: "docker";
95
+ fly: "fly";
96
+ }>>;
97
+ compose: z.ZodDefault<z.ZodBoolean>;
98
+ packageManager: z.ZodEnum<{
99
+ pnpm: "pnpm";
100
+ npm: "npm";
101
+ yarn: "yarn";
102
+ bun: "bun";
103
+ }>;
104
+ codingAgents: z.ZodDefault<z.ZodArray<z.ZodEnum<{
105
+ claude: "claude";
106
+ cursor: "cursor";
107
+ codex: "codex";
108
+ }>>>;
109
+ }, z.core.$strict>;
110
+ type ProjectSpec = z.output<typeof ProjectSpecSchema>;
111
+ type ProjectSpecInput = z.input<typeof ProjectSpecSchema>;
112
+ /**
113
+ * Parses and normalizes a spec: lists are deduplicated and sorted the way the
114
+ * catalogs list them, so two specs that mean the same project are equal.
115
+ */
116
+ declare function parseSpec(input: unknown): ProjectSpec;
117
+ /** The model as the runtime addresses it: `provider/model`. */
118
+ declare function qualifiedModel(spec: Pick<ProjectSpec, 'provider' | 'model'>): string;
119
+ /** The model without the provider prefix, as provider APIs and `ollama pull` name it. */
120
+ declare function bareModel(spec: Pick<ProjectSpec, 'provider' | 'model'>): string;
121
+
122
+ /** A variable the generated project reads from its environment. */
123
+ interface EnvVar {
5
124
  name: string;
6
- path: string;
7
- template: Template;
8
- provider: LLMProvider;
125
+ /** One line for `.env.example` and the env schema. */
126
+ description: string;
127
+ /** The value `.env.example` shows; secrets show an empty value. */
128
+ example?: string;
129
+ /** Whether the project refuses to start without it. */
130
+ required: boolean;
131
+ /** Whether it is a credential: never logged, kept out of `.env.example` values. */
132
+ secret: boolean;
9
133
  /**
10
- * The model the agents use, without the provider prefix (`qwen3.5:9b`, `gpt-6.1-sol`).
11
- * Defaults to the provider's entry in `defaultModels`.
134
+ * Whether a deployment must provide it, listed in `cogitator.yml` as a
135
+ * `deploy.secrets` entry. Defaults to secrets the project requires.
12
136
  */
13
- model?: string;
14
- packageManager: PackageManager;
15
- docker: boolean;
16
- git: boolean;
17
- /** Run `<packageManager> install` after writing the files (default `true`). */
18
- install?: boolean;
137
+ deploy?: boolean;
19
138
  }
20
- /** How an optional step of `scaffold()` went. */
21
- type ScaffoldStep = {
139
+ /** A command that takes the project to its first run, with an optional explanation. */
140
+ interface NextStep {
141
+ command: string;
142
+ note?: string;
143
+ }
144
+ interface GeneratedFile {
145
+ path: string;
146
+ /** Mutable until the plan is done, so a final pass can adapt every file. */
147
+ content: string;
148
+ /** File mode for `chmod`, used for `.env` (0600) and executable scripts. */
149
+ mode?: number;
150
+ }
151
+
152
+ /** What is already done when the next steps are shown. */
153
+ interface SetupState {
154
+ /** Where the project is relative to the user's shell; no `cd` step when absent. */
155
+ directory?: string;
156
+ installed: boolean;
157
+ /** Whether the provider key was written to `.env`. */
158
+ keyWritten: boolean;
159
+ /** Whether the Ollama model is known to be pulled. */
160
+ modelReady: boolean;
161
+ }
162
+
163
+ interface PlanOptions {
164
+ /** Values for `.env`, such as the provider key. Never written anywhere else. */
165
+ secrets?: Record<string, string>;
166
+ /** `name@version` of the package manager, written to package.json's `packageManager`. */
167
+ packageManagerSpec?: string;
168
+ }
169
+ /** Everything a project consists of, computed without touching the disk. */
170
+ interface ProjectPlan {
171
+ spec: ProjectSpec;
172
+ files: GeneratedFile[];
173
+ dependencies: Record<string, string>;
174
+ devDependencies: Record<string, string>;
175
+ scripts: Record<string, string>;
176
+ env: EnvVar[];
177
+ /** Compose services the project starts locally. */
178
+ services: string[];
179
+ warnings: string[];
180
+ /** The command that creates this project again. */
181
+ command: string;
182
+ /** The steps to the first run, before anything is installed. */
183
+ nextSteps(state: SetupState): NextStep[];
184
+ }
185
+ /** What package.json records under `cogitator` so `cogitator add` can grow the project. */
186
+ interface ScaffoldManifest {
187
+ generator: string;
188
+ spec: ProjectSpec;
189
+ command: string;
190
+ }
191
+ declare const MANIFEST_KEY = "cogitator";
192
+ /**
193
+ * The project `spec` describes. Throws when the spec is invalid or its parts do
194
+ * not fit together, before anything is generated.
195
+ */
196
+ declare function planProject(input: unknown, options?: PlanOptions): ProjectPlan;
197
+
198
+ /**
199
+ * Where the scaffolder reports progress. The CLI shows it with spinners, the
200
+ * programmatic API stays silent unless a logger is passed.
201
+ */
202
+ interface ScaffoldLogger {
203
+ start(message: string): void;
204
+ done(message: string): void;
205
+ fail(message: string): void;
206
+ warn(message: string): void;
207
+ }
208
+ declare const silentLogger: ScaffoldLogger;
209
+ /** How an optional step went. */
210
+ type StepResult = {
22
211
  status: 'done';
23
212
  } | {
24
213
  status: 'skipped';
214
+ reason: string;
25
215
  } | {
26
216
  status: 'failed';
27
217
  error: Error;
28
218
  };
29
- /** What `scaffold()` did: the project is written even when a later step failed. */
219
+ interface ScaffoldOptions extends PlanOptions {
220
+ /** The directory to create the project in. It must not exist or be empty. */
221
+ directory: string;
222
+ /** Run the package manager's install (default `true`). */
223
+ install?: boolean;
224
+ /** Initialize a git repository and commit the project (default `true`). */
225
+ git?: boolean;
226
+ log?: ScaffoldLogger;
227
+ /** Show the install's output live instead of capturing it. */
228
+ inheritOutput?: boolean;
229
+ }
30
230
  interface ScaffoldResult {
31
- /** The generated files, relative to the project directory. */
231
+ plan: ProjectPlan;
232
+ directory: string;
233
+ /** The generated files, relative to `directory`. */
32
234
  files: string[];
33
- /** `<packageManager> install`, skipped with `install: false`. */
34
- install: ScaffoldStep;
35
- /** `git init` and the first commit, skipped with `git: false` or when git is not installed. */
36
- git: ScaffoldStep;
235
+ install: StepResult;
236
+ format: StepResult;
237
+ git: StepResult;
238
+ /** The workspace root above the project, when it was created inside one. */
239
+ parentWorkspace?: string;
240
+ }
241
+ /** Hashes of the files the scaffolder wrote, so `cogitator add` can tell them from files the user edited. */
242
+ interface ScaffoldLock {
243
+ version: 1;
244
+ generator: string;
245
+ files: Record<string, string>;
37
246
  }
38
- interface TemplateFile {
247
+ declare const LOCK_PATH = ".cogitator/scaffold.json";
248
+ declare function hashContent(content: string): string;
249
+ declare function writeFiles(directory: string, files: readonly GeneratedFile[]): Promise<void>;
250
+ declare function writeLock(directory: string, paths: readonly string[]): Promise<void>;
251
+ /**
252
+ * Re-hashes `paths` in the lock after `cogitator add` wrote or deleted them,
253
+ * keeping the hashes of every other file.
254
+ */
255
+ declare function updateLock(directory: string, paths: readonly string[]): Promise<void>;
256
+ declare function readLock(directory: string): ScaffoldLock | undefined;
257
+ /**
258
+ * Formats the generated code with the project's own Biome, so it starts clean
259
+ * under `lint`: the whole project, or only `paths` when they are given.
260
+ */
261
+ declare function formatProject(directory: string, paths?: readonly string[]): Promise<StepResult>;
262
+ /**
263
+ * Creates the project `spec` describes in `options.directory`, then installs
264
+ * its dependencies, formats it and commits it to a new git repository. Throws
265
+ * when the spec is invalid or the directory is taken. A failed install, format
266
+ * or git step does not throw: the result reports it and the project stays.
267
+ */
268
+ declare function scaffold(spec: unknown, options: ScaffoldOptions): Promise<ScaffoldResult>;
269
+
270
+ /** What `cogitator add` brings into a project. Lists are added to, the rest replaced. */
271
+ interface AddChanges {
272
+ features?: readonly FeatureId[];
273
+ channels?: readonly ChannelKind[];
274
+ codingAgents?: readonly CodingAgent[];
275
+ memory?: MemoryKind;
276
+ vectorStore?: VectorStore;
277
+ deploy?: DeployTarget;
278
+ }
279
+ /** A file `cogitator add` writes or removes, with the diff against what is on disk. */
280
+ interface FileChange {
39
281
  path: string;
40
- content: string;
282
+ kind: 'create' | 'update' | 'delete';
283
+ /** The new content, absent for a deletion. */
284
+ content?: string;
285
+ /** How the content came about: generated as a whole, or merged into the user's copy. */
286
+ source: 'generated' | 'merged';
287
+ diff: string;
41
288
  }
42
- interface TemplateGenerator {
43
- /**
44
- * The path the generated app answers health checks on, written to
45
- * cogitator.yml as `deploy.health.path` so `cogitator deploy` probes it.
46
- * Absent for templates that run as scripts rather than servers.
47
- */
48
- healthPath?: string;
49
- /**
50
- * The memory adapter the generated code configures, written to cogitator.yml so
51
- * `cogitator deploy` provisions the services it needs. Absent when it keeps none.
52
- */
53
- memoryAdapter?: 'memory' | 'redis';
54
- /**
55
- * Environment variables the deployed app needs besides the provider key, written
56
- * to cogitator.yml as `deploy.secrets` together with that key.
57
- */
58
- secrets?: string[];
59
- files(options: ProjectOptions): TemplateFile[];
60
- dependencies(): Record<string, string>;
61
- devDependencies(): Record<string, string>;
62
- scripts(): Record<string, string>;
289
+ /** Something the addition left as it is on purpose. */
290
+ interface AddNote {
291
+ message: string;
292
+ path?: string;
293
+ /** The change that was not applied, when there is one. */
294
+ diff?: string;
295
+ }
296
+ /** A file the user changed in a way the addition cannot be merged into. */
297
+ interface AddConflict {
298
+ path: string;
299
+ reason: string;
300
+ /** The change the addition needs to make to the file as generated. */
301
+ diff: string;
302
+ }
303
+ interface AddPlan {
304
+ directory: string;
305
+ from: ProjectSpec;
306
+ to: ProjectSpec;
307
+ /** What changes in the spec, one item per line: `feature rag`, `memory sqlite -> postgres`. */
308
+ summary: string[];
309
+ changes: FileChange[];
310
+ conflicts: AddConflict[];
311
+ /** What was left as it is on purpose, and why. */
312
+ notes: AddNote[];
313
+ /** Dependencies the project gains or whose version changes. */
314
+ dependencies: Record<string, string>;
315
+ devDependencies: Record<string, string>;
316
+ /** Dependencies and dev dependencies the merged package.json no longer lists. */
317
+ removedDependencies: string[];
318
+ /** Environment variables the project starts reading. */
319
+ env: EnvVar[];
320
+ /** Compose services the project starts using. */
321
+ services: string[];
322
+ warnings: string[];
323
+ /** The command that creates the project as it is after the addition. */
324
+ command: string;
325
+ /** Whether the project already has everything asked for. */
326
+ upToDate: boolean;
327
+ }
328
+ interface AddOptions {
329
+ /** Install when the dependencies change (default `true`). */
330
+ install?: boolean;
331
+ log?: ScaffoldLogger;
332
+ /** Show the install's output live instead of capturing it. */
333
+ inheritOutput?: boolean;
334
+ }
335
+ interface AddResult {
336
+ plan: AddPlan;
337
+ /** Files written, relative to the project. */
338
+ written: string[];
339
+ deleted: string[];
340
+ install: StepResult;
341
+ format: StepResult;
342
+ }
343
+ /** Thrown when the project is not one the scaffolder generated, so its parts are unknown. */
344
+ declare class NotAScaffoldedProjectError extends Error {
345
+ constructor(message: string);
346
+ }
347
+ /** Thrown when an addition would overwrite changes the user made. Nothing is written. */
348
+ declare class AddConflictError extends Error {
349
+ readonly conflicts: AddConflict[];
350
+ constructor(conflicts: AddConflict[]);
63
351
  }
352
+ /**
353
+ * Whether the addition changes what the project depends on, in either
354
+ * direction: the lockfile and the installed tree need an install either way.
355
+ */
356
+ declare function changesDependencies(plan: AddPlan): boolean;
357
+ /**
358
+ * What adding `changes` to the project in `directory` would do, without
359
+ * writing anything. The project's spec is read from package.json, both the
360
+ * project as it is and as it would be are planned, and what the addition
361
+ * changes between them is merged into the files on disk. A file the user
362
+ * edited takes the change when it can be merged key by key (package.json,
363
+ * cogitator.yml, docker-compose.yml, the managed block of AGENTS.md,
364
+ * .gitignore), and is a conflict otherwise.
365
+ */
366
+ declare function planAdd(directory: string, changes: AddChanges): AddPlan;
367
+ /**
368
+ * Adds `changes` to the project in `directory`: plans the addition, refuses
369
+ * with an `AddConflictError` when it would overwrite the user's edits, then
370
+ * writes the files, installs new dependencies, formats what it wrote and
371
+ * records the new spec and file hashes. Adding what the project already has
372
+ * changes nothing.
373
+ */
374
+ declare function addToProject(directory: string, changes: AddChanges, options?: AddOptions): Promise<AddResult>;
64
375
 
65
376
  /**
66
- * Writes the project described by `options`, then installs its dependencies
67
- * (unless `install` is `false`) and initializes git (when `git` is `true`).
68
- * Throws when `name` is not a valid package name or `path` exists and is not
69
- * empty. A failed install or git step does not throw: the result reports it,
70
- * and the project stays written.
377
+ * A unified diff from `before` to `after`, as `git diff` prints it, or an
378
+ * empty string when they are equal. A missing side is `undefined`: the file
379
+ * is created or deleted.
71
380
  */
72
- declare function scaffold(options: ProjectOptions): Promise<ScaffoldResult>;
381
+ declare function unifiedDiff(path: string, before: string | undefined, after: string | undefined): string;
73
382
 
74
- interface ParsedArgs {
75
- name?: string;
76
- template?: Template;
77
- provider?: LLMProvider;
78
- model?: string;
383
+ /** An example of the Cogitator repo, as `--example` turns it into a project. Indexed at build time. */
384
+ interface ExampleEntry {
385
+ /** `core/basic-agent`: the category and the file name without its number. */
386
+ name: string;
387
+ title: string;
388
+ /** The runnable file, relative to `examples/`. */
389
+ entry: string;
390
+ /** Every file the project needs, relative to `examples/`. */
391
+ files: string[];
392
+ dependencies: Record<string, string>;
393
+ devDependencies: Record<string, string>;
394
+ /** Environment variables the files read. */
395
+ env: string[];
396
+ /** What runs the example: Node through tsx, or Bun for examples that use its APIs. */
397
+ runtime: 'node' | 'bun';
398
+ }
399
+ /** The examples indexed when the scaffolder was built, from the `examples/` it is released with. */
400
+ declare function examples(): ExampleEntry[];
401
+ /** The git tag the examples of a scaffolder version are fetched from. */
402
+ declare function exampleRef(version: string): string;
403
+ /** `name#ref` as `--example` takes it. */
404
+ declare function parseExampleArgument(value: string): {
405
+ query: string;
406
+ ref?: string;
407
+ };
408
+ /**
409
+ * The example `query` names: `core/basic-agent`, its file `core/01-basic-agent`
410
+ * or `core/01-basic-agent.ts`, or just `basic-agent` when only one category
411
+ * has it. Throws with the closest names otherwise.
412
+ */
413
+ declare function findExample(query: string, index?: readonly ExampleEntry[]): ExampleEntry;
414
+ /** Where the raw content of `examples/<path>` is at `ref`. */
415
+ declare function exampleFileUrl(ref: string, path: string): string;
416
+ interface ExamplePlanOptions {
417
+ name: string;
418
+ packageManager: PackageManager;
419
+ version: string;
420
+ ref: string;
421
+ /** Values for `.env`. */
422
+ secrets?: Record<string, string>;
423
+ }
424
+ interface ExamplePlan {
425
+ example: ExampleEntry;
426
+ ref: string;
427
+ /** Files generated around the example. */
428
+ files: GeneratedFile[];
429
+ /** The example's own files, fetched from GitHub, relative to `examples/`. */
430
+ remoteFiles: string[];
431
+ command: string;
432
+ scripts: Record<string, string>;
433
+ }
434
+ /** The project around an example: package.json, tsconfig, .env.example, README and the rest. */
435
+ declare function planExample(example: ExampleEntry, options: ExamplePlanOptions): ExamplePlan;
436
+ /** Fetches the example's own files from GitHub at the plan's ref. */
437
+ declare function fetchExampleFiles(plan: ExamplePlan, fetchImpl?: typeof fetch): Promise<GeneratedFile[]>;
438
+
439
+ /** A template fetched from a GitHub repository instead of generated: `github:owner/repo[/path][#ref]`. */
440
+ interface RemoteTemplate {
441
+ owner: string;
442
+ repo: string;
443
+ path?: string;
444
+ ref?: string;
445
+ }
446
+ declare function describeTemplate(template: RemoteTemplate): string;
447
+ /**
448
+ * Where the archive of `template` is. With a token it goes through the GitHub
449
+ * API, which serves private repositories; without one through codeload.
450
+ */
451
+ declare function templateArchive(template: RemoteTemplate, token?: string): {
452
+ url: string;
453
+ headers: Record<string, string>;
454
+ };
455
+ interface DownloadResult {
456
+ /** Files written, relative to the directory. */
457
+ files: string[];
458
+ /** Entries left out: links and special files, which a template has no business shipping. */
459
+ skipped: string[];
460
+ }
461
+ /**
462
+ * Downloads `template` and extracts it, or its `path` inside the repository,
463
+ * into `directory`. Only regular files and directories are written, none
464
+ * outside `directory`.
465
+ */
466
+ declare function downloadTemplate(template: RemoteTemplate, directory: string, options?: {
467
+ fetch?: typeof fetch;
468
+ token?: string;
469
+ }): Promise<DownloadResult>;
470
+ interface PreparedTemplate {
471
+ /** The package manager its lockfile belongs to, when it has one. */
79
472
  packageManager?: PackageManager;
80
- docker?: boolean;
81
- git?: boolean;
473
+ /** Dependencies rewritten from `workspace:` to published versions. */
474
+ rewritten: string[];
475
+ }
476
+ /**
477
+ * Makes an extracted template a project of its own: package.json gets the
478
+ * project's name, and `workspace:` ranges of `@cogitator-ai/*` packages, which
479
+ * templates from a monorepo carry, become the versions released with the
480
+ * scaffolder. Other workspace and catalog ranges cannot be resolved outside
481
+ * their monorepo and are refused.
482
+ */
483
+ declare function prepareTemplate(directory: string, options: {
484
+ name: string;
485
+ }): PreparedTemplate;
486
+
487
+ interface StarterOptions {
488
+ directory: string;
489
+ name: string;
490
+ packageManager: PackageManager;
82
491
  install?: boolean;
83
- yes?: boolean;
492
+ git?: boolean;
493
+ log?: ScaffoldLogger;
494
+ inheritOutput?: boolean;
495
+ fetch?: typeof fetch;
84
496
  }
85
- declare function parseArgs(args: string[]): ParsedArgs;
497
+ /** A project made from an example or a remote template instead of the generator. */
498
+ interface StarterResult {
499
+ directory: string;
500
+ /** Where it came from: `example core/basic-agent at create-cogitator-app@0.4.0` or `github:owner/repo`. */
501
+ source: string;
502
+ files: string[];
503
+ packageManager: PackageManager;
504
+ install: StepResult;
505
+ git: StepResult;
506
+ /** Commands to the first run. */
507
+ nextSteps: NextStep[];
508
+ notes: string[];
509
+ }
510
+ /** The project `--example` describes, before anything is fetched or written. */
511
+ declare function resolveExample(argument: string, options: Pick<StarterOptions, 'name' | 'packageManager'> & {
512
+ secrets?: Record<string, string>;
513
+ }): ExamplePlan;
514
+ /**
515
+ * Creates a project from an example of the Cogitator repo: its files at the
516
+ * tag of this scaffolder version (or the ref after `#`), with a package.json,
517
+ * tsconfig, .env.example and README around them.
518
+ */
519
+ declare function createFromExample(plan: ExamplePlan, options: StarterOptions): Promise<StarterResult>;
86
520
  /**
87
- * Turn the parsed arguments into project options, asking for whatever they leave
88
- * out; with `--yes` nothing is asked and the defaults fill the gaps.
521
+ * Creates a project from a GitHub repository or a directory of one. The
522
+ * repository's lockfile decides the package manager when it has one.
523
+ * Nothing is left behind when the download fails.
89
524
  */
90
- declare function collectOptions(args: ParsedArgs): Promise<ProjectOptions>;
525
+ declare function createFromTemplate(template: RemoteTemplate, options: StarterOptions & {
526
+ token?: string;
527
+ }): Promise<StarterResult>;
91
528
 
92
- declare function getTemplate(name: Template): TemplateGenerator;
93
- declare const templateChoices: Array<{
94
- value: Template;
529
+ /** A combination the generated project could not work with, and how to fix it. */
530
+ interface CompatIssue {
531
+ message: string;
532
+ fix: string;
533
+ }
534
+ /**
535
+ * Every reason `spec` describes a project that would not work, empty when it is
536
+ * consistent. Checked before any file is written, so an impossible project is
537
+ * refused instead of generated half-broken.
538
+ */
539
+ declare function compatibilityIssues(spec: ProjectSpec): CompatIssue[];
540
+ declare class IncompatibleSpecError extends Error {
541
+ readonly issues: CompatIssue[];
542
+ constructor(issues: CompatIssue[]);
543
+ }
544
+ declare function assertCompatible(spec: ProjectSpec): void;
545
+
546
+ /** The parts of a spec a preset fixes: everything except the name, provider and tooling. */
547
+ type PresetSpec = Pick<ProjectSpecInput, 'app' | 'server' | 'channels' | 'memory' | 'vectorStore' | 'features'> & {
548
+ provider?: ProjectSpecInput['provider'];
549
+ };
550
+ interface Preset {
551
+ id: string;
95
552
  label: string;
96
553
  hint: string;
97
- }>;
554
+ spec: PresetSpec;
555
+ /** Earlier names of the preset that `--template` still accepts. */
556
+ aliases?: string[];
557
+ }
558
+ /**
559
+ * Named starting points. Every preset is a combination of the stack axes, so a
560
+ * preset project can grow with `cogitator add` like any other.
561
+ */
562
+ declare const PRESETS: readonly Preset[];
563
+ declare const DEFAULT_PRESET = "basic";
564
+ declare function findPreset(idOrAlias: string): Preset | undefined;
565
+ declare function presetIds(): string[];
566
+
567
+ interface Choice<T extends string> {
568
+ value: T;
569
+ label: string;
570
+ hint: string;
571
+ }
572
+ declare const APP_CHOICES: Choice<AppKind>[];
573
+ declare const SERVER_CHOICES: Choice<ServerFramework>[];
574
+ declare const MEMORY_CHOICES: Choice<MemoryKind>[];
575
+ declare const VECTOR_STORE_CHOICES: Choice<VectorStore>[];
576
+ declare const FEATURE_CHOICES: Choice<FeatureId>[];
577
+ declare const DEPLOY_CHOICES: Choice<DeployTarget>[];
578
+ declare const CHANNEL_CHOICES: Choice<ChannelKind>[];
579
+ declare const CODING_AGENT_CHOICES: Choice<CodingAgent>[];
580
+
581
+ interface ProviderInfo {
582
+ id: LLMProvider;
583
+ label: string;
584
+ /** The variable the API key is read from, absent for providers without one. */
585
+ envKey?: string;
586
+ /** Where to create an API key. */
587
+ keyUrl?: string;
588
+ /** The model a new project uses unless another one is chosen. */
589
+ defaultModel: string;
590
+ /** The embedding model RAG uses with this provider, absent when it has none. */
591
+ embeddingModel?: string;
592
+ /** The dimensions of `embeddingModel`, which vector stores size their collections by. */
593
+ embeddingDimensions?: number;
594
+ /** Whether the provider has a realtime voice API Cogitator drives. */
595
+ realtime: boolean;
596
+ /** A short line for prompts and `--help`. */
597
+ hint: string;
598
+ }
599
+ declare const PROVIDER_INFO: Record<LLMProvider, ProviderInfo>;
600
+ declare function providerInfo(provider: LLMProvider): ProviderInfo;
601
+ declare function providerEnvKey(provider: LLMProvider): string | undefined;
602
+ declare function defaultModel(provider: LLMProvider): string;
603
+ /**
604
+ * Small models with reliable tool calling that run on a laptop, offered when
605
+ * Ollama is not reachable to list what is installed.
606
+ */
607
+ declare const OLLAMA_SUGGESTED_MODELS: readonly ["qwen3.5:9b", "qwen3.5:4b", "gemma4:e4b", "llama3.1:8b", "mistral-small3.2:24b"];
608
+ declare const DEFAULT_OLLAMA_URL = "http://localhost:11434";
609
+
610
+ interface ModelChoice {
611
+ /** The model id without the provider prefix. */
612
+ value: string;
613
+ label: string;
614
+ hint?: string;
615
+ }
616
+ /** Where the choices came from: the live catalogue, the built-in list, the local Ollama, or a fallback. */
617
+ type ModelSource = 'catalog' | 'builtin' | 'ollama' | 'suggested';
618
+ interface ModelChoices {
619
+ choices: ModelChoice[];
620
+ source: ModelSource;
621
+ }
622
+ /** `$2 in / $10 out per 1M tokens, 1M context`, the line a model choice shows. */
623
+ declare function describeModel(model: Pick<ModelInfo, 'pricing' | 'contextWindow'>): string;
624
+ /**
625
+ * The current models of a cloud provider: its built-in lineup from
626
+ * `@cogitator-ai/models`, with prices and context windows refreshed from the
627
+ * live catalogue when it answers in time. The provider's default comes first.
628
+ */
629
+ declare function cloudModelChoices(provider: Exclude<LLMProvider, 'ollama'>, options?: {
630
+ timeoutMs?: number;
631
+ registry?: Pick<ModelRegistry, 'initialize' | 'getModel'>;
632
+ }): Promise<ModelChoices>;
633
+ /**
634
+ * The models of the local Ollama, with the recommended one first and marked as
635
+ * installed or not. When Ollama does not answer, a list of small models with
636
+ * reliable tool calling to pull.
637
+ */
638
+ declare function ollamaModelChoices(baseUrl?: string): Promise<ModelChoices>;
639
+ declare function modelChoices(provider: LLMProvider): Promise<ModelChoices>;
640
+
641
+ /** What checking an API key found out. The key itself never appears in it. */
642
+ type KeyCheck = {
643
+ status: 'valid';
644
+ } | {
645
+ status: 'rate-limited';
646
+ } | {
647
+ status: 'invalid';
648
+ httpStatus: number;
649
+ } | {
650
+ status: 'unreachable';
651
+ reason: string;
652
+ } | {
653
+ status: 'unexpected';
654
+ httpStatus: number;
655
+ };
656
+ /** Checks that `key` is accepted by `provider`, within `timeoutMs`. */
657
+ declare function checkApiKey(provider: Exclude<LLMProvider, 'ollama'>, key: string, options?: {
658
+ timeoutMs?: number;
659
+ fetch?: typeof fetch;
660
+ }): Promise<KeyCheck>;
661
+ /** One line for the user about a key check. */
662
+ declare function describeKeyCheck(envKey: string, check: KeyCheck): string;
663
+
664
+ interface OllamaModel {
665
+ name: string;
666
+ size: number;
667
+ }
668
+ /**
669
+ * The Ollama server the generated code talks to: `OLLAMA_BASE_URL`, which it
670
+ * reads, then `OLLAMA_HOST`, which the Ollama CLI reads, then the local default.
671
+ */
672
+ declare function resolveOllamaUrl(env?: Record<string, string | undefined>): string;
673
+ /** The models installed in the Ollama at `baseUrl`, or `undefined` when it does not answer. */
674
+ declare function listOllamaModels(baseUrl: string, timeoutMs?: number): Promise<OllamaModel[] | undefined>;
675
+ /** Whether `model` is among `installed`, treating a name without a tag as `:latest` like Ollama does. */
676
+ declare function hasOllamaModel(installed: readonly OllamaModel[], model: string): boolean;
677
+ /** Pulls `model` into the Ollama at `baseUrl`, reporting each status line; throws when the pull fails. */
678
+ declare function pullOllamaModel(baseUrl: string, model: string, onStatus: (status: string) => void): Promise<void>;
98
679
 
99
680
  /**
100
681
  * The package manager that launched the scaffolder, read from the
101
682
  * `npm_config_user_agent` it sets (`npm/10.9.8 node/v22...` under npx), or pnpm
102
683
  * when there is none.
103
684
  */
104
- declare function detectPackageManager(): PackageManager;
105
- declare function devCommand(pm: PackageManager): string;
685
+ declare function detectPackageManager(userAgent?: string | undefined): PackageManager;
686
+ /**
687
+ * The `packageManager` field for the pnpm, Yarn or Bun that runs the scaffolder,
688
+ * e.g. `pnpm@10.26.0`, so corepack and the deploy image install with the same
689
+ * version. Undefined for npm, which corepack leaves alone, and when the version
690
+ * is unknown.
691
+ */
692
+ declare function detectPackageManagerSpec(pm: PackageManager, userAgent?: string | undefined): string | undefined;
693
+ /** The command that runs the package.json script `script`. */
694
+ declare function runScript(pm: PackageManager, script: string, args?: string): string;
695
+ /** The command that runs a binary of an installed package. */
696
+ declare function execCommand(pm: PackageManager, bin: string): string;
697
+ declare function installCommand(pm: PackageManager): string;
106
698
 
107
- declare const defaultModels: Record<LLMProvider, string>;
108
- declare function providerEnvKey(provider: LLMProvider): string;
699
+ /** The version of create-cogitator-app itself, inlined at build time. */
700
+ declare function scaffolderVersion(): string;
701
+ type CogitatorPackage = `@cogitator-ai/${string}`;
702
+ /** The range a generated project depends on for `name`: a caret on the version released with the scaffolder. */
703
+ declare function cogitatorVersion(name: CogitatorPackage): string;
704
+ /** Every `@cogitator-ai/*` version the scaffolder knows, for `--json` and diagnostics. */
705
+ declare function knownCogitatorVersions(): Record<string, string>;
109
706
  /**
110
- * How generated code reads the provider's API key: `requireEnv` calls the
111
- * `requireEnv` helper of the generated `src/env.ts`, which fails at startup
112
- * with the name of the missing variable. `process-env` reads `process.env` and
113
- * leaves a missing key to the first request, for code a build imports without
114
- * the key, such as a Next.js route.
707
+ * Third-party packages generated projects depend on, in one place so every
708
+ * feature asks for the same range. Ranges follow the current majors.
115
709
  */
116
- type ApiKeyAccess = 'requireEnv' | 'process-env';
117
- /** The `llm` section of the generated `new Cogitator({...})` call. */
118
- declare function providerConfig(provider: LLMProvider, access?: ApiKeyAccess): string;
710
+ declare const VERSIONS: {
711
+ readonly zod: "^4.6.5";
712
+ readonly typescript: "^7.0.2";
713
+ readonly typesNode: "^24.19.1";
714
+ readonly tsx: "^4.23.15";
715
+ readonly vitest: "^5.0.3";
716
+ readonly biome: "^2.5.15";
717
+ readonly express: "^5.2.1";
718
+ readonly typesExpress: "^5.0.6";
719
+ readonly fastify: "^5.12.5";
720
+ readonly fastifyCors: "^11.3.0";
721
+ readonly hono: "^4.13.13";
722
+ readonly honoNodeServer: "^2.1.3";
723
+ readonly koa: "^3.2.1";
724
+ readonly koaRouter: "^15.7.0";
725
+ readonly typesKoa: "^3.0.3";
726
+ readonly typesKoaRouter: "^15.0.0";
727
+ readonly koaCors: "^5.0.0";
728
+ readonly typesKoaCors: "^5.0.1";
729
+ readonly koaBodyparser: "^6.1.0";
730
+ readonly tetsuCore: "^0.6.3";
731
+ readonly tetsuSse: "^0.6.3";
732
+ readonly tetsuOpenapi: "^0.6.3";
733
+ readonly typesBun: "^1.4.2";
734
+ readonly next: "^16.4.0";
735
+ readonly react: "^19.3.0";
736
+ readonly reactDom: "^19.3.0";
737
+ readonly typesReact: "^19.3.0";
738
+ readonly typesReactDom: "^19.3.0";
739
+ readonly tailwind: "^4.3.3";
740
+ readonly tailwindPostcss: "^4.3.3";
741
+ readonly reactMarkdown: "^10.1.0";
742
+ readonly betterSqlite3: "^13.0.3";
743
+ readonly pg: "^8.23.1";
744
+ readonly ioredis: "^6.0.0";
745
+ readonly mongodb: "^7.7.0";
746
+ readonly qdrant: "^1.19.0";
747
+ readonly grammy: "^1.46.0";
748
+ readonly discord: "^14.27.0";
749
+ readonly slackBolt: "^5.1.0";
750
+ readonly ws: "^8.22.0";
751
+ readonly langfuse: "^3.39.2";
752
+ readonly modelContextProtocol: "^1.32.1";
753
+ };
754
+ /** Container images compose and deploy use, pinned so a project starts the same way every time. */
755
+ declare const IMAGES: {
756
+ readonly redis: "redis:8.8-alpine";
757
+ readonly postgres: "pgvector/pgvector:0.8.7-pg18-trixie";
758
+ readonly mongodb: "mongo:8.3";
759
+ readonly qdrant: "qdrant/qdrant:v1.19.2";
760
+ readonly ollama: "ollama/ollama:0.40.0";
761
+ readonly jaeger: "jaegertracing/jaeger:2.22.0";
762
+ };
119
763
 
764
+ /** Where the events go: the Umami instance of the Cogitator project. */
765
+ declare const TELEMETRY_HOST = "https://analytics.el1fe.com";
766
+ declare const TELEMETRY_DOCS = "https://cogitator.app/docs/getting-started/telemetry";
120
767
  /**
121
- * Why `name` cannot be the generated package's name, or `undefined` when it can.
122
- * The name lands in package.json and in generated code, so it has to be a valid
123
- * unscoped npm package name.
768
+ * The Umami website the events are counted under, set when the scaffolder is
769
+ * built for a release (`COGITATOR_UMAMI_WEBSITE_ID`). A build without it sends
770
+ * nothing.
124
771
  */
125
- declare function validateProjectName(name: string): string | undefined;
772
+ declare function telemetryWebsiteId(): string;
773
+ /**
774
+ * Everything one event carries, and nothing else: no project name, path,
775
+ * model, key or anything a user typed.
776
+ */
777
+ interface TelemetryPayload {
778
+ version: string;
779
+ /** The preset, `custom` for a stack picked by hand, `example` or `template` for copied projects. */
780
+ preset: string;
781
+ provider: string;
782
+ memory: string;
783
+ /** The add-ons, comma-separated in catalog order. */
784
+ features: string;
785
+ packageManager: string;
786
+ /** The major version of Node, such as `24`. */
787
+ node: string;
788
+ /** `darwin`, `linux` or `win32`. */
789
+ os: string;
790
+ outcome: 'success' | 'failure';
791
+ }
792
+ declare const PAYLOAD_FIELDS: ReadonlyArray<keyof TelemetryPayload>;
793
+ declare function payloadFor(spec: Pick<ProjectSpec, 'preset' | 'provider' | 'memory' | 'features' | 'packageManager'> | undefined, outcome: TelemetryPayload['outcome'], kind?: 'generated' | 'example' | 'template'): TelemetryPayload;
794
+ /** Why no event is sent, or `undefined` when one is. */
795
+ declare function telemetryDisabledReason(options: {
796
+ flag?: boolean;
797
+ dryRun?: boolean;
798
+ env?: NodeJS.ProcessEnv;
799
+ websiteId?: string;
800
+ }): string | undefined;
801
+ /**
802
+ * The one line about telemetry shown the first time it is on, or `undefined`
803
+ * when it was shown before. Showing it is remembered in the user's config
804
+ * directory.
805
+ */
806
+ declare function firstRunNotice(env?: NodeJS.ProcessEnv): string | undefined;
807
+ /**
808
+ * Sends the event to Umami. It never throws and never takes longer than its
809
+ * timeout: a slow or failing network changes nothing for the scaffolder.
810
+ */
811
+ declare function sendTelemetry(payload: TelemetryPayload, options?: {
812
+ fetch?: typeof fetch;
813
+ websiteId?: string;
814
+ host?: string;
815
+ timeoutMs?: number;
816
+ }): Promise<boolean>;
817
+
818
+ interface Io {
819
+ stdout: (text: string) => void;
820
+ stderr: (text: string) => void;
821
+ }
822
+ /** What `run` reaches the network and the environment with, replaceable in tests. */
823
+ interface RunDeps {
824
+ fetch?: typeof fetch;
825
+ env?: NodeJS.ProcessEnv;
826
+ /** Where telemetry goes, the release's Umami website by default. */
827
+ telemetry?: {
828
+ websiteId?: string;
829
+ host?: string;
830
+ fetch?: typeof fetch;
831
+ };
832
+ }
833
+ /** Runs the scaffolder for `argv` and resolves with the exit code. */
834
+ declare function run(argv: readonly string[], io?: Io, deps?: RunDeps): Promise<number>;
835
+
836
+ /** The candidate closest to `input`, when it is close enough to be a typo of it. */
837
+ declare function closest(input: string, candidates: readonly string[]): string | undefined;
126
838
 
127
- export { type LLMProvider, type PackageManager, type ProjectOptions, type ScaffoldResult, type ScaffoldStep, type Template, type TemplateFile, collectOptions, defaultModels, detectPackageManager, devCommand, getTemplate, parseArgs, providerConfig, providerEnvKey, scaffold, templateChoices, validateProjectName };
839
+ export { APP_CHOICES, APP_KINDS, type AddChanges, type AddConflict, AddConflictError, type AddNote, type AddOptions, type AddPlan, type AddResult, type AppKind, CHANNELS, CHANNEL_CHOICES, CODING_AGENTS, CODING_AGENT_CHOICES, type ChannelKind, type Choice, type CodingAgent, type CompatIssue, DEFAULT_OLLAMA_URL, DEFAULT_PRESET, DEPLOY_CHOICES, DEPLOY_TARGETS, type DeployTarget, type DownloadResult, type ExampleEntry, type ExamplePlan, type ExamplePlanOptions, FEATURES, FEATURE_CHOICES, type FeatureId, type FileChange, IMAGES, IncompatibleSpecError, type KeyCheck, type LLMProvider, LOCK_PATH, MANIFEST_KEY, MEMORIES, MEMORY_CHOICES, type MemoryKind, type ModelChoice, type ModelChoices, type ModelSource, NotAScaffoldedProjectError, OLLAMA_SUGGESTED_MODELS, type OllamaModel, PACKAGE_MANAGERS, PAYLOAD_FIELDS, PRESETS, PROVIDERS, PROVIDER_INFO, type PackageManager, type PlanOptions, type PreparedTemplate, type Preset, type ProjectPlan, type ProjectSpec, type ProjectSpecInput, ProjectSpecSchema, type ProviderInfo, type RemoteTemplate, SERVERS, SERVER_CHOICES, type ScaffoldLock, type ScaffoldLogger, type ScaffoldManifest, type ScaffoldOptions, type ScaffoldResult, type ServerFramework, type StarterOptions, type StarterResult, type StepResult, TELEMETRY_DOCS, TELEMETRY_HOST, type TelemetryPayload, VECTOR_STORES, VECTOR_STORE_CHOICES, VERSIONS, type VectorStore, addToProject, assertCompatible, bareModel, changesDependencies, checkApiKey, closest, cloudModelChoices, cogitatorVersion, compatibilityIssues, createFromExample, createFromTemplate, defaultModel, describeKeyCheck, describeModel, describeTemplate, detectPackageManager, detectPackageManagerSpec, downloadTemplate, exampleFileUrl, exampleRef, examples, execCommand, fetchExampleFiles, findExample, findPreset, firstRunNotice, formatProject, hasOllamaModel, hashContent, installCommand, knownCogitatorVersions, listOllamaModels, modelChoices, ollamaModelChoices, parseExampleArgument, parseSpec, payloadFor, planAdd, planExample, planProject, prepareTemplate, presetIds, providerEnvKey, providerInfo, pullOllamaModel, qualifiedModel, readLock, resolveExample, resolveOllamaUrl, run, runScript, scaffold, scaffolderVersion, sendTelemetry, silentLogger, telemetryDisabledReason, telemetryWebsiteId, templateArchive, unifiedDiff, updateLock, validateProjectName, writeFiles, writeLock };