@okfit/cli 0.2.0 → 0.4.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/index.d.ts CHANGED
@@ -1,99 +1,28 @@
1
- import { ConfigReadError, ConfigReadError as ConfigReadError$1 } from "@effected/config-file";
2
- import { Context, DateTime, Effect, FileSystem, Layer, Option, Path, PlatformError, Runtime, Schema } from "effect";
3
- import { Git, GitCommandError, UnknownRefError } from "@effected/git";
4
- import { BundleLoadError, Diagnostic, DiagnosticRange, DiagnosticSeverity, LoadedBundle, OkfitConfig, OkfitConfigFile, ValidationReport } from "@okfit/core";
5
- import { GitHistory, GitHistoryError, Layout, Profile, ProfileDiagnostic } from "@okfit/profiles";
6
1
  import { Command } from "effect/unstable/cli";
7
- import { AppDirs, Xdg } from "@effected/xdg";
8
- import { FrontmatterWriteError, MarkdownParseError } from "@effected/markdown";
9
- //#region src/errors.d.ts
10
- declare const ConfigPathNotFoundError_base: Schema.Class<ConfigPathNotFoundError, Schema.TaggedStruct<"ConfigPathNotFoundError", {
11
- readonly path: Schema.String;
12
- }>, import("effect/Cause").YieldableError>;
13
- /**
14
- * `--config <path>` named a path that does not exist. Every `ConfigResolver`
15
- * has a `never` error channel and `explicitPath` absorbs a missing target
16
- * into `Option.none()`, so a bad `--config` would otherwise fall through to
17
- * the XDG file silently. The CLI checks it itself before building any layer
18
- * (K-1, spec 4.1).
19
- *
20
- * @public
21
- */
22
- export declare class ConfigPathNotFoundError extends ConfigPathNotFoundError_base {
23
- readonly [Runtime.errorExitCode] = 3;
24
- get message(): string;
25
- }
26
- declare const InitOverwriteError_base: Schema.Class<InitOverwriteError, Schema.TaggedStruct<"InitOverwriteError", {
27
- readonly paths: Schema.$Array<Schema.String>;
28
- readonly cwd: Schema.String;
29
- }>, import("effect/Cause").YieldableError>;
30
- /**
31
- * `okfit init` found one or more of its target paths already present (K-28).
32
- * Carries the whole conflicting-path list so the renderer prints every one.
33
- * `paths` are absolute; `renderFailure` relativises them to `cwd` (K-51).
34
- *
35
- * @public
36
- */
37
- export declare class InitOverwriteError extends InitOverwriteError_base {
38
- readonly [Runtime.errorExitCode] = 3;
39
- get message(): string;
40
- }
41
- declare const VerifyConceptNotFoundError_base: Schema.Class<VerifyConceptNotFoundError, Schema.TaggedStruct<"VerifyConceptNotFoundError", {
42
- readonly id: Schema.String;
43
- readonly root: Schema.String;
44
- readonly reason: Schema.Literals<readonly ["not-a-concept", "reserved", "undecodable"]>;
45
- readonly diagnosticCode: Schema.optionalKey<Schema.String>;
46
- }>, import("effect/Cause").YieldableError>;
47
- /**
48
- * V-9: `<id>` did not resolve to a verifiable concept. `reason` is
49
- * `"not-a-concept"` (no such file, or an id that normalises to nothing),
50
- * `"reserved"` (the id names `index.md` or `log.md`), or `"undecodable"`
51
- * (a file exists but `bundle.diagnostics` names it — `diagnosticCode`
52
- * carries which). `root` is the absolute bundle root, kept OFF `message`
53
- * so K-51's relativisation rule has nothing to apply to and the human
54
- * line and the JSON envelope's `message` are identical.
55
- *
56
- * @public
57
- */
58
- export declare class VerifyConceptNotFoundError extends VerifyConceptNotFoundError_base {
59
- readonly [Runtime.errorExitCode] = 3;
60
- get message(): string;
61
- }
62
- declare const VerifyUnsupportedFrontmatterError_base: Schema.Class<VerifyUnsupportedFrontmatterError, Schema.TaggedStruct<"VerifyUnsupportedFrontmatterError", {
63
- readonly id: Schema.String;
64
- readonly shape: Schema.String;
65
- }>, import("effect/Cause").YieldableError>;
2
+ import { ContextEnvelope, RenderedDiagnostic } from "@okfit/engine";
3
+ import "effect";
4
+ //#region src/commands/root.d.ts
66
5
  /**
67
- * V-14: fail closed on a `verified` shape the classifier does not name.
68
- * `shape` is one of `"alias"`, `"merge-key"`, `"scalar"`, `"empty"` (and,
69
- * defensively, `"no-frontmatter"` or `"not-a-mapping"`, neither reachable
70
- * for a concept that reached `bundle.concepts`). The file is never opened
71
- * for writing when this is raised.
6
+ * K-5. No handler: the framework's own default for a command with neither a
7
+ * `handle` nor a matched subcommand is
8
+ * `Effect.fail(new CliError.ShowHelp({ commandPath, errors: [] }))`, and a
9
+ * `ShowHelp` with no errors carries `[Runtime.errorExitCode] = 0`. Bare
10
+ * `okfit` therefore prints the root help and exits `0` with no code in this
11
+ * package at all.
72
12
  *
73
- * @public
74
- */
75
- export declare class VerifyUnsupportedFrontmatterError extends VerifyUnsupportedFrontmatterError_base {
76
- readonly [Runtime.errorExitCode] = 3;
77
- get message(): string;
78
- }
79
- declare const ConfigMalformedError_base: Schema.Class<ConfigMalformedError, Schema.TaggedStruct<"ConfigMalformedError", {
80
- readonly path: Schema.String;
81
- readonly cause: Schema.Defect;
82
- }>, import("effect/Cause").YieldableError>;
83
- /**
84
- * A config file at a KNOWN path failed to parse or validate (K-46's own
85
- * intent — "each class' message already names the offending path" does not
86
- * hold for `@effected/config-file`'s `ConfigCodecError`, which carries no
87
- * `path` field at all; this wraps it, and `ConfigValidationError`, with the
88
- * path the caller already knows). `cause` is the original config-file error,
89
- * preserved structurally, never stringified early.
13
+ * `validate`, `init`, `context`, `verify`, and `sync` are the whole command tree;
14
+ * nothing else is registered here. Each is appended in introduction order,
15
+ * never reordered in, so `--help`'s subcommand list reads that way too
16
+ * (contract §4.2). The top-level description is left unchanged: neither
17
+ * `context` nor `verify` validates or scaffolds, but widening the sentence
18
+ * for the orientation- and attestation-only commands buys nothing
19
+ * (contract §4.2).
90
20
  *
91
21
  * @public
92
22
  */
93
- export declare class ConfigMalformedError extends ConfigMalformedError_base {
94
- readonly [Runtime.errorExitCode] = 3;
95
- get message(): string;
96
- }
23
+ export declare const rootCommand: Command.Command<"okfit", {} | {}, {}, import("@okfit/profiles").AgentActorUnconfiguredError | import("@okfit/core").BundleDepthExceededError | import("@okfit/core").BundleReadError | import("@okfit/core").BundleRootNotFoundError | import("@effected/config-file").ConfigCodecError | import("@effected/config-file").ConfigFileReadError | import("@okfit/engine").ConfigMalformedError | import("@okfit/engine").ConfigPathNotFoundError | import("@effected/config-file").ConfigValidationError | import("@effected/markdown").FrontmatterEncodeError | import("@effected/markdown").FrontmatterFormatMismatchError | import("@effected/markdown").FrontmatterValidationError | import("@effected/git").GitCommandError | import("@okfit/profiles").GitHistoryError | import("@okfit/profiles").HumanActorUnresolvedError | import("@okfit/engine").InitOverwriteError | import("@effected/markdown").MarkdownParseError | import("@effected/git").NotARepositoryError | import("effect/PlatformError").PlatformError | import("effect/Schema").SchemaError | import("@effected/git").UnknownRefError | import("@okfit/engine").VerifyConceptNotFoundError | import("@okfit/engine").VerifyUnsupportedFrontmatterError | import("@effected/yaml").YamlParseError, import("@effected/xdg").AppDirs | import("effect/unstable/process/ChildProcessSpawner").ChildProcessSpawner | import("effect/Crypto").Crypto | import("effect/FileSystem").FileSystem | import("@okfit/engine").Now | import("effect/Path").Path | import("@effected/xdg").Xdg>;
24
+ //#endregion
25
+ //#region src/errors.d.ts
97
26
  /**
98
27
  * The `render` option for `CliRuntime.reportFailures` (K-30, K-46, K-51). One
99
28
  * string per stderr line; `reportFailures` emits each through its own
@@ -135,482 +64,7 @@ export declare class ConfigMalformedError extends ConfigMalformedError_base {
135
64
  */
136
65
  export declare const renderFailure: (error: unknown) => ReadonlyArray<string>;
137
66
  //#endregion
138
- //#region src/validate/run.d.ts
139
- declare const Now_base: Context.ServiceClass<Now, "@okfit/cli/Now", DateTime.Utc>;
140
- /**
141
- * K-47's ambient clock. `bin.ts` resolves `OKFIT_NOW` (or the wall clock)
142
- * exactly once and provides it with `Effect.provideService(Now, value)`
143
- * around the whole command tree; `commands/validate.ts` and
144
- * `commands/init.ts` each read it with `const now = yield* Now;` before
145
- * building {@link RunOptions} or a scaffold's `today`. Not re-exported from
146
- * `index.ts`: like `internal/exit.ts` and `internal/tty.ts`, it means
147
- * nothing outside a spawned process (K-49). `Context.Tag` does not exist on
148
- * the Effect v4 line; the v4 shape is
149
- * `Context.Service<Self, Shape>()(id)`, the same form core and profiles use
150
- * for their own services (`PROFILES/GitHistory.ts:140`) — source wins over
151
- * the contract's literal snippet here (K-62).
152
- *
153
- * @internal
154
- */
155
- declare class Now extends Now_base {}
156
- /** @public */
157
- interface RunOptions {
158
- /** Absolute bundle root; `Bundle.load` never reads cwd (D-8). */
159
- readonly root: string;
160
- /** Already merged `DEFAULTS < profile < file` by the caller (D-28). */
161
- readonly config: OkfitConfig;
162
- /** The resolved profile, when `Profiles.get` found one. */
163
- readonly profile: Option.Option<Profile>;
164
- /** `OKFIT_NOW` or `DateTime.now`, from `bin.ts` (K-47); enables the `stale` rule (D-34). */
165
- readonly now: DateTime.Utc;
166
- /**
167
- * S-31: skip `Provenance.lint`'s git tier for this one invocation,
168
- * without touching the project's `[lint]` table. `commands/validate.ts`
169
- * threads `--skip-provenance` here; the PostToolUse hook passes the flag
170
- * so an edit-time `validate` stays git-free even when the config leaves
171
- * `generated-at-drift` at its default severity. Defaults to `false`, and
172
- * is checked the same way `severity === "off"` already is — `run` skips
173
- * the walk when EITHER is true.
174
- */
175
- readonly skipProvenance?: boolean;
176
- }
177
- /** @public */
178
- interface RunResult {
179
- readonly bundle: LoadedBundle;
180
- readonly report: ValidationReport;
181
- /** `[]` when `profile` is `None`. */
182
- readonly profileDiagnostics: ReadonlyArray<ProfileDiagnostic>;
183
- }
184
- /**
185
- * Load, validate both tiers, run the profile check, then — UNLESS the
186
- * `generated-at-drift` lint is `off` OR `options.skipProvenance` is `true`
187
- * — run `Provenance.lint` and append its `Diagnostic`s to `report.lint`.
188
- * The "skip the git walk entirely" gate lives HERE, in `run`, not inside
189
- * `Provenance.lint` (S-8's own wording): a bundle configured `off`, or a
190
- * caller that passed `--skip-provenance`, never pays for a git spawn
191
- * (S-31). An `error` severity on the appended diagnostics yields exit `1`
192
- * through the EXISTING lint-tier rule in `render/exit.ts` — no renderer
193
- * branch, no new `DiagnosticSource`, since these diagnostics flow through
194
- * the same `report.lint` array every other core lint diagnostic already
195
- * does.
196
- *
197
- * K-52 holds structurally: `Bundle.load`'s failure short-circuits the
198
- * generator, so `profile.check` never runs on a bundle that did not load.
199
- *
200
- * This is a BREAKING signature change: `@okfit/mcp`'s `validateBundle.ts`
201
- * calls this function directly and must be updated to match (Task C1);
202
- * `commands/validate.ts` is the other caller.
203
- *
204
- * @public
205
- */
206
- export declare const run: (options: RunOptions) => Effect.Effect<RunResult, BundleLoadError | GitHistoryError | GitCommandError | UnknownRefError | PlatformError.PlatformError, FileSystem.FileSystem | Path.Path | Git | GitHistory>;
207
- //#endregion
208
- //#region src/commands/root.d.ts
209
- /**
210
- * K-5. No handler: the framework's own default for a command with neither a
211
- * `handle` nor a matched subcommand is
212
- * `Effect.fail(new CliError.ShowHelp({ commandPath, errors: [] }))`, and a
213
- * `ShowHelp` with no errors carries `[Runtime.errorExitCode] = 0`. Bare
214
- * `okfit` therefore prints the root help and exits `0` with no code in this
215
- * package at all.
216
- *
217
- * `validate`, `init`, `context`, `verify`, and `sync` are the whole command tree;
218
- * nothing else is registered here. Each is appended in introduction order,
219
- * never reordered in, so `--help`'s subcommand list reads that way too
220
- * (contract §4.2). The top-level description is left unchanged: neither
221
- * `context` nor `verify` validates or scaffolds, but widening the sentence
222
- * for the orientation- and attestation-only commands buys nothing
223
- * (contract §4.2).
224
- *
225
- * @public
226
- */
227
- export declare const rootCommand: Command.Command<"okfit", {} | {}, {}, import("@okfit/profiles").AgentActorUnconfiguredError | import("@okfit/core").BundleDepthExceededError | import("@okfit/core").BundleReadError | import("@okfit/core").BundleRootNotFoundError | import("@effected/config-file").ConfigCodecError | import("@effected/config-file").ConfigFileReadError | ConfigMalformedError | ConfigPathNotFoundError | import("@effected/config-file").ConfigValidationError | import("@effected/markdown").FrontmatterEncodeError | import("@effected/markdown").FrontmatterFormatMismatchError | import("@effected/markdown").FrontmatterValidationError | import("@effected/git").GitCommandError | import("@okfit/profiles").GitHistoryError | import("@okfit/profiles").HumanActorUnresolvedError | InitOverwriteError | import("@effected/markdown").MarkdownParseError | import("@effected/git").NotARepositoryError | import("effect/PlatformError").PlatformError | import("effect/Schema").SchemaError | import("@effected/git").UnknownRefError | VerifyConceptNotFoundError | VerifyUnsupportedFrontmatterError | import("@effected/yaml").YamlParseError, import("@effected/xdg").AppDirs | import("effect/unstable/process/ChildProcessSpawner").ChildProcessSpawner | import("effect/FileSystem").FileSystem | Now | import("effect/Path").Path | import("@effected/xdg").Xdg>;
228
- //#endregion
229
- //#region src/config/anchor.d.ts
230
- /**
231
- * What {@link resolveProjectRoot} needs about the winning discovery source
232
- * (K-12, K-58). Narrower than `@effected/config-file`'s own
233
- * `ConfigSource`: only `path`, `resolver` and the match's `dir` matter for
234
- * anchoring, and a caller building this from a real
235
- * `ConfigSource<OkfitConfig>` simply drops `value`.
236
- *
237
- * @public
238
- */
239
- interface DiscoveredConfig {
240
- /** `ConfigSource.path` — absolute. */
241
- readonly path: string;
242
- /** `ConfigSource.resolver` — the resolver's `name`. */
243
- readonly resolver: string;
244
- /**
245
- * `ConfigSource.match?.dir` — the ancestor directory `upwardWalk`
246
- * anchored the winning candidate against. Absent when the resolver did
247
- * not implement `resolveMatch`, or reported no `dir` (`explicitPath`
248
- * never does, by design).
249
- */
250
- readonly dir?: string;
251
- }
252
- /**
253
- * K-12's project root, as amended by K-58 and C1-2, in order:
254
- *
255
- * 1. `pathArg`, if given. `Argument.path` has already resolved it absolute.
256
- * 2. otherwise, if `--config` was given: `anchorForExplicit` applied to that
257
- * path.
258
- * 3. otherwise, if a config was discovered by the `"project"` resolver
259
- * (`ConfigResolver.upwardWalk`, named `"project"` in `layer.ts`) AND it
260
- * reported a `dir`: that `dir` verbatim — it is already the ancestor
261
- * `upwardWalk` anchored the match against (the parent of `.config` for a
262
- * `.config/okfit.toml` candidate, the candidate's own directory
263
- * otherwise), so no path-tail test is needed here any more.
264
- * 4. otherwise `cwd` — this covers every other resolver name (`"xdg"`,
265
- * `"native"`, `"system"`) as defence in depth, a `"project"` match with no
266
- * `dir` (should not happen, since `upwardWalk` always reports one), and
267
- * no discovery at all.
268
- *
269
- * The CLI never probes for `.git` (K-12), even though
270
- * `ConfigResolver.gitRoot` exists.
271
- *
272
- * @public
273
- */
274
- export declare const resolveProjectRoot: (input: {
275
- readonly pathArg: Option.Option<string>;
276
- readonly explicitConfigPath: Option.Option<string>;
277
- readonly discovered: Option.Option<DiscoveredConfig>;
278
- readonly cwd: string;
279
- readonly path: Path.Path;
280
- }) => string;
281
- /**
282
- * `<project root>/<bundle.path>`, absolute (K-2). `config` is the MERGED
283
- * config, so `bundle.path` is `OkfitConfig.DEFAULTS.bundle.path` (`"okf"`)
284
- * unless a file or profile overrode it. The bundle root is never what
285
- * `[path]` names.
286
- *
287
- * @public
288
- */
289
- export declare const resolveBundleRoot: (projectRoot: string, config: OkfitConfig, path: Path.Path) => string;
290
- //#endregion
291
- //#region src/config/layer.d.ts
292
- /**
293
- * The `OkfitConfigFile` layer for one invocation (K-9 to K-11, K-57, C-6),
294
- * now one `AppConfig.layer(OkfitConfigFile, ...)` call in both branches; only
295
- * the chain options vary:
296
- *
297
- * - `explicitConfigPath` is `Some`: `resolvers: [ConfigResolver.explicitPath(path)]`
298
- * and `xdg: false` — K-10's "only that path" rule, so the chain is exactly
299
- * one resolver and no `systemEtc` tier is added either.
300
- * - `explicitConfigPath` is `None`: `resolvers: [ConfigResolver.upwardWalk({ filenames, ... })]`
301
- * carrying C-1's three per-directory candidates (`.okfit.toml`,
302
- * `okfit.toml`, `.config/okfit.toml`, directory-major so a child's later
303
- * candidate beats a parent's earlier one — C-2's ascent to the filesystem
304
- * root is `upwardWalk`'s own default with no `stopAt`), named `"project"`
305
- * so `resolve.ts`/`anchor.ts` can identify it without string-matching a
306
- * path tail. `systemEtc` is C-5's `/etc` tier, present unless
307
- * `systemConfigDir` overrides its root (tests only — no production call
308
- * site sets it). `xdg` and `native` stay on their defaults (C-4), which is
309
- * what puts personal defaults at `$XDG_CONFIG_HOME/okfit/config.toml` and
310
- * the native probe behind it.
311
- *
312
- * `filename: "config.toml"` is the same in both branches — it is the XDG/
313
- * native/system tiers' filename, unrelated to the C-1 project names above.
314
- * `defaultPath` is `AppConfig.layer`'s own `XdgConfig.savePath(filename)`, so
315
- * `save`/`update` do not fail with `ConfigDefaultPathMissingError`; nothing
316
- * here sets it explicitly any more.
317
- *
318
- * `discoveryCwd` is `[path]` when given, else `process.cwd()` (K-2), passed
319
- * straight through as `upwardWalk`'s own `cwd` so nothing in this module
320
- * reads the process.
321
- *
322
- * `App.layer`, `AppStore` and `AppCache` appear nowhere, so no
323
- * `store.db`/`cache.db` is ever created (K-9).
324
- *
325
- * @public
326
- */
327
- export declare const buildConfigLayer: (options: {
328
- readonly explicitConfigPath: Option.Option<string>;
329
- readonly discoveryCwd: string;
330
- /**
331
- * System config root, defaulting to `/etc`. Overridable primarily so tests
332
- * can point at a writable temp directory — the real `/etc` is not writable
333
- * in test environments. No production call site sets it.
334
- */
335
- readonly systemConfigDir?: string;
336
- }) => Layer.Layer<OkfitConfigFile, never, FileSystem.FileSystem | Path.Path | AppDirs | Xdg>;
337
- /**
338
- * The K-1 pre-flight and the provide, in that order and in one place: stat
339
- * `explicitConfigPath` with `FileSystem.exists` and fail with
340
- * `ConfigPathNotFoundError` BEFORE `buildConfigLayer` is called at all. This
341
- * is why the CLI does not use `Command.provide(cmd, (input) => layer)`,
342
- * which would construct the layer first (Judge notes 9) — here the stat
343
- * runs as the first step of one `Effect.gen`, and `buildConfigLayer` is only
344
- * reached, and only then actually run, on the step after it.
345
- *
346
- * `FileSystem.FileSystem.exists` is `(path: string) => Effect.Effect<boolean, PlatformError>`
347
- * (`EF/FileSystem.ts:143-145`), not infallible, so
348
- * `PlatformError.PlatformError` joins the error channel here (decision 7):
349
- * an unusual stat failure (e.g. a permission error on a parent directory)
350
- * renders through `renderFailure`'s catch-all rule rather than being
351
- * uncatchable by the type checker.
352
- *
353
- * K-46/K-63 fix: a `ConfigCodecError`/`ConfigValidationError` from
354
- * `buildConfigLayer`'s provided layer is wrapped into `ConfigMalformedError`
355
- * whenever the failing path is known, so `renderFailure` can name it:
356
- *
357
- * - `ConfigCodecError` now carries its own `path: string | undefined`
358
- * (config-file 0.7.0, `ConfigFile.discover` re-raises with `path` attached
359
- * at every site that fed the codec a path it resolved) — used when
360
- * present, so a malformed file found during DISCOVERY (no `--config`) now
361
- * also wraps into `ConfigMalformedError` naming the candidate that failed,
362
- * closing the K-63 gap. It falls back to `explicitConfigPath` only when
363
- * the library's own `path` is `undefined` and `--config` was given; only
364
- * when neither is known does the cause pass through unwrapped.
365
- * - `ConfigValidationError` carries its own `path: Option<string>` — used
366
- * when present (either branch), falling back to `explicitConfigPath` when
367
- * the library's own `path` is `None` and `--config` was given.
368
- *
369
- * @public
370
- */
371
- export declare const provideConfig: (options: {
372
- readonly explicitConfigPath: Option.Option<string>;
373
- readonly discoveryCwd: string;
374
- readonly systemConfigDir?: string;
375
- }) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E | ConfigPathNotFoundError | ConfigMalformedError | PlatformError.PlatformError, Exclude<R, OkfitConfigFile> | FileSystem.FileSystem | Path.Path | AppDirs | Xdg>;
376
- //#endregion
377
- //#region src/config/resolve.d.ts
378
- /**
379
- * `OkfitConfig.DEFAULTS.bundle.profile` is `"software-project"` at runtime
380
- * (the frozen literal always sets it), but `bundle` and `profile` are both
381
- * `optionalKey` in the schema, so the type checker sees `string | undefined`
382
- * two levels deep. The `?? "software-project"` fallback here is unreachable
383
- * in practice; it exists only to satisfy `noUncheckedIndexedAccess`-style
384
- * strictness without a non-null assertion. Formerly duplicated identically
385
- * in `commands/validate.ts` and `commands/context.ts`; this is its one home
386
- * now that both commands delegate to {@link resolveProjectConfig}.
387
- *
388
- * @public
389
- */
390
- export declare const DEFAULT_PROFILE_NAME: string;
391
- /**
392
- * Everything `validate` and `context`'s handlers derive from config
393
- * discovery before diverging (contract §8.3): the merged config, the
394
- * resolved profile (and its name after the "none"/default rule), the
395
- * discovery source (if any), and the project/bundle roots.
396
- *
397
- * @public
398
- */
399
- interface ResolvedProjectConfig {
400
- readonly projectRoot: string;
401
- readonly bundleRoot: string;
402
- readonly config: OkfitConfig;
403
- readonly profile: Option.Option<Profile>;
404
- readonly profileName: string;
405
- readonly discovered: Option.Option<DiscoveredConfig>;
406
- }
407
- /**
408
- * Input to {@link resolveProjectConfig}: the same three values every command
409
- * handler already has in hand (its own `[path]` argument, its own
410
- * `--config` flag, and `process.cwd()`) — nothing this function needs is
411
- * read from `process` itself.
412
- *
413
- * @public
414
- */
415
- interface ResolveProjectConfigInput {
416
- readonly pathArg: Option.Option<string>;
417
- readonly explicitConfigPath: Option.Option<string>;
418
- readonly cwd: string;
419
- }
420
- /**
421
- * The config-resolution step byte-identical between `validate` and
422
- * `context`'s handlers (A2 review finding): discover, pick `sources[0]`,
423
- * default `{ extensions: {} }`, resolve the profile name and the K-4
424
- * unknown-profile warning, merge `DEFAULTS < profile < file` (D-28), warn on
425
- * an `okf_version` mismatch (K-15), then resolve the project and bundle
426
- * roots (K-12). Every message string and the merge order are unchanged from
427
- * the two commands' former inline copies.
428
- *
429
- * @public
430
- */
431
- export declare const resolveProjectConfig: (input: ResolveProjectConfigInput) => Effect.Effect<ResolvedProjectConfig, ConfigReadError$1, OkfitConfigFile | Path.Path>;
432
- //#endregion
433
- //#region src/context/run.d.ts
434
- /** @public */
435
- interface ContextRunOptions {
436
- readonly bundleRoot: string;
437
- }
438
- /** @public */
439
- interface ContextResult {
440
- readonly indexPath: string;
441
- readonly indexExists: boolean;
442
- }
443
- /**
444
- * The whole of `context`'s filesystem work: join `index.md` onto the bundle
445
- * root and stat it. Loading a bundle and running conformance/lint checks
446
- * over it never happen here — that is what makes `context` cheap enough
447
- * for a hook to run on every session start and every in-bundle write
448
- * (M-15).
449
- *
450
- * `"index.md"` is a literal here, not read from the profile's layout: the
451
- * spec fixes the reserved filename regardless of profile, and a
452
- * profile-less merge (`profile = "none"`) has no layout to read from at
453
- * all — `context` behaves identically with and without a profile.
454
- *
455
- * `exists` is `(path) => Effect.Effect<boolean, PlatformError>`, so an
456
- * unreadable parent directory would otherwise fail the command; here it is
457
- * absorbed to `false`, because "the hook could not stat index.md" and
458
- * "index.md is not there" are the same fact from a consumer's point of
459
- * view.
460
- *
461
- * @public
462
- */
463
- export declare const runContext: (options: ContextRunOptions) => Effect.Effect<ContextResult, never, FileSystem.FileSystem | Path.Path>;
464
- //#endregion
465
- //#region src/init/scaffold.d.ts
466
- /** `.config/okfit.toml`, relative to the project root (C-10). @public */
467
- export declare const CONFIG_RELATIVE_PATH = ".config/okfit.toml";
468
- /** @public */
469
- interface ScaffoldOptions {
470
- /** Absolute. */
471
- readonly projectRoot: string;
472
- /** Absolute; `<projectRoot>/<bundle.path>`. */
473
- readonly bundleRoot: string;
474
- /** The resolved profile's `layout` (`PROFILES/Profile.ts:35-38`, P-26). */
475
- readonly layout: Layout;
476
- /** The name written into the config and the log entry. */
477
- readonly profileName: string;
478
- /** `basename(projectRoot)` — `project.md`'s `title` (K-26). */
479
- readonly projectTitle: string;
480
- /** `YYYY-MM-DD`, derived from the CLI's `now` (K-25, K-47). */
481
- readonly today: string;
482
- }
483
- /** One file `init` will write. Pure data; this module imports no `FileSystem`. @public */
484
- interface ScaffoldFile {
485
- /** Absolute. */
486
- readonly path: string;
487
- readonly contents: string;
488
- }
489
- /**
490
- * K-23: the THIN override only — never the merged config. `bundle.path` is
491
- * the bundle root relative to the project root; `extensions: {}` satisfies
492
- * `OkfitConfig`'s one non-optional field (`CORE/OkfitConfig.ts:164`).
493
- * Everything else resolves from `DEFAULTS` and the profile at load time.
494
- * `actors.agent` is deliberately absent (K-24, P-17).
495
- *
496
- * @public
497
- */
498
- export declare const configValue: (options: ScaffoldOptions & {
499
- readonly bundlePath: string;
500
- }) => OkfitConfig;
501
- /**
502
- * Every path `init` will create, absolute, in write order, for the K-28
503
- * pre-flight: the three project-level config names, the bundle root's
504
- * `index.md`/`log.md`/`project.md`, then one `index.md` per layout directory
505
- * in `layout`'s own declared order — never re-sorted here. `Derive.renderIndex`
506
- * sorts its own `Subdirectories` section independently (C13), so this
507
- * function's order has no bearing on the rendered index text.
508
- *
509
- * @public
510
- */
511
- export declare const targetPaths: (options: ScaffoldOptions) => ReadonlyArray<string>;
512
- /**
513
- * The three root markdown files and the per-directory indexes (K-25 to
514
- * K-27, K-59). `project.md`'s frontmatter is written with
515
- * `MarkdownFrontmatter.setToString` — the INSERT path, since the body below
516
- * carries no frontmatter block of its own (`MD/index.d.ts:1959`,
517
- * `FrontmatterWriteError`'s own doc comment: "a document with no frontmatter
518
- * capture is the insert path, not an error"). The root `index.md` is
519
- * `Derive.renderIndex` over a `LoadedConcept` this function synthesizes from
520
- * the just-rendered `project.md` text, re-parsed with `MarkdownDocument.parse`
521
- * (K-59; `renderIndex` reads only `frontmatter.type`/`title`/`description`
522
- * and `path`, never `document`, `CORE/Derive.ts:75-101`, so the synthesized
523
- * value is faithful). Each per-directory `index.md` is the literal
524
- * `# <Directory>` — NOT `Derive.renderIndex`, which returns the empty string
525
- * for an empty concept list with no options (contract Judge notes item 2).
526
- *
527
- * @public
528
- */
529
- export declare const files: (options: ScaffoldOptions) => Effect.Effect<ReadonlyArray<ScaffoldFile>, MarkdownParseError | FrontmatterWriteError>;
530
- //#endregion
531
67
  //#region src/render/context.d.ts
532
- /** One `types[]` entry (M-15). @public */
533
- export declare const ContextType: Schema.Struct<{
534
- readonly name: Schema.String;
535
- readonly description: Schema.NullOr<Schema.String>;
536
- readonly guidance: Schema.NullOr<Schema.String>;
537
- }>;
538
- /** @public */
539
- export type ContextType = typeof ContextType.Type;
540
- /** One `tags[]` entry (M-15). @public */
541
- export declare const ContextTag: Schema.Struct<{
542
- readonly name: Schema.String;
543
- readonly description: Schema.NullOr<Schema.String>;
544
- }>;
545
- /** @public */
546
- export type ContextTag = typeof ContextTag.Type;
547
- /**
548
- * M-15's envelope: schema 1, snake_case, orientation data only. Distinct
549
- * from `JsonEnvelope` (`render/json.ts`) — `context` never runs conformance
550
- * or lint checks, so there is no `diagnostics` array and no `exit_code`
551
- * field at all.
552
- *
553
- * Every field is `Schema.NullOr`, never `Schema.optionalKey`: a consumer
554
- * (the two hook scripts) reads a fixed key set and gets JSON `null` for an
555
- * absent value, rather than having to distinguish a missing key from a
556
- * null one. This is a deliberate difference from `JsonDiagnostic`'s
557
- * `range`, which is `optionalKey` and omitted when absent
558
- * (`render/json.ts:14,68`).
559
- *
560
- * `profile_requested` (final-review Important 1) is the profile name the
561
- * config asked for after the K-4 default rule — `resolveProjectConfig`'s
562
- * own `profileName` — and is `null` only when no config file was found at
563
- * all. `profile` keeps its original meaning (the resolved profile's name,
564
- * or `null` when the requested name is unknown or `"none"`). The two
565
- * differ exactly when a config named an unrecognised profile: `profile`
566
- * is `null` but `profile_requested` still names what was asked for, so a
567
- * consumer can tell "no profile configured" apart from "an unknown profile
568
- * was configured".
569
- *
570
- * @public
571
- */
572
- export declare const ContextEnvelope: Schema.Struct<{
573
- readonly schema: Schema.Literal<1>;
574
- readonly project_root: Schema.String;
575
- readonly bundle_root: Schema.String;
576
- readonly config_path: Schema.NullOr<Schema.String>;
577
- readonly profile: Schema.NullOr<Schema.String>;
578
- readonly profile_requested: Schema.NullOr<Schema.String>;
579
- readonly index_path: Schema.String;
580
- readonly index_exists: Schema.Boolean;
581
- readonly actors: Schema.Struct<{
582
- readonly agent: Schema.NullOr<Schema.String>;
583
- }>;
584
- readonly types: Schema.$Array<Schema.Struct<{
585
- readonly name: Schema.String;
586
- readonly description: Schema.NullOr<Schema.String>;
587
- readonly guidance: Schema.NullOr<Schema.String>;
588
- }>>;
589
- readonly tags: Schema.$Array<Schema.Struct<{
590
- readonly name: Schema.String;
591
- readonly description: Schema.NullOr<Schema.String>;
592
- }>>;
593
- }>;
594
- /** @public */
595
- export type ContextEnvelope = typeof ContextEnvelope.Type;
596
- /**
597
- * Build the envelope from the merged config. `types`/`tags` sort by `name`
598
- * with plain code-unit comparison, never locale-dependent — the same rule
599
- * `render/sort.ts`'s K-17 comparator and
600
- * `packages/profiles/src/SoftwareProject.ts:119`'s own sort use.
601
- *
602
- * @public
603
- */
604
- export declare const contextEnvelope: (input: {
605
- readonly projectRoot: string;
606
- readonly bundleRoot: string;
607
- readonly configPath: string | null;
608
- readonly profile: string | null;
609
- readonly profileRequested: string | null;
610
- readonly indexPath: string;
611
- readonly indexExists: boolean;
612
- readonly config: OkfitConfig;
613
- }) => ContextEnvelope;
614
68
  /**
615
69
  * The `human` format: a short header block, then one line per type and one
616
70
  * per tag. Pure; the caller pipes each line through `Console.log`.
@@ -624,76 +78,6 @@ export declare const contextEnvelope: (input: {
624
78
  */
625
79
  export declare const humanContext: (envelope: ContextEnvelope) => ReadonlyArray<string>;
626
80
  //#endregion
627
- //#region src/render/sort.d.ts
628
- /** Which producer a diagnostic came from; the JSON envelope's `source` (K-21). @public */
629
- type DiagnosticSource = "core.conformance" | "core.lint" | "profile";
630
- /**
631
- * The one shape both renderers consume. `file` is the bundle-relative posix
632
- * path core produced, `""` for a bundle-level finding. `range` is core's own
633
- * zero-based `DiagnosticRange` instance, passed through untouched (K-21).
634
- * `code` is widened to `string`: core's `DiagnosticCode`
635
- * (`CORE/Diagnostic.ts:45-46`) and profiles' `ProfileDiagnosticCode`
636
- * (`PROFILES/Profile.ts:47`) are disjoint closed unions and this carries
637
- * either.
638
- *
639
- * @public
640
- */
641
- interface RenderedDiagnostic {
642
- readonly source: DiagnosticSource;
643
- readonly file: string;
644
- readonly range?: DiagnosticRange;
645
- readonly code: string;
646
- readonly severity: DiagnosticSeverity;
647
- readonly message: string;
648
- }
649
- /**
650
- * Tag core's two arrays and profiles' one, in producer order. Not named
651
- * `merge`: `OkfitConfig.merge` already owns that word in this codebase.
652
- *
653
- * @public
654
- */
655
- export declare const collect: (conformance: ReadonlyArray<Diagnostic>, lint: ReadonlyArray<Diagnostic>, profile: ReadonlyArray<ProfileDiagnostic>) => ReadonlyArray<RenderedDiagnostic>;
656
- /**
657
- * K-17: `file` ascending (so `""` — the bundle-level finding — leads), then
658
- * range-less before ranged within a file, then `range.offset` ascending, then
659
- * `code`. Plain code-unit comparison, never locale-dependent (the same rule
660
- * profiles' own `check` sorts by, `PROFILES/SoftwareProject.ts:119`). Stable:
661
- * implemented with `toSorted`, which is specified as stable.
662
- *
663
- * @public
664
- */
665
- export declare const sort: (diagnostics: ReadonlyArray<RenderedDiagnostic>) => ReadonlyArray<RenderedDiagnostic>;
666
- //#endregion
667
- //#region src/render/exit.d.ts
668
- /** @public */
669
- interface Tally {
670
- readonly conformanceErrors: number;
671
- readonly lintErrors: number;
672
- readonly lintWarnings: number;
673
- readonly lintInfo: number;
674
- readonly profileErrors: number;
675
- }
676
- /**
677
- * One pass over the collected diagnostics. `core.conformance` entries are
678
- * always severity `error` (D-33); the counts are still taken from `severity`
679
- * so a future non-error conformance code cannot silently change the exit
680
- * code.
681
- *
682
- * @public
683
- */
684
- export declare const tally: (diagnostics: ReadonlyArray<RenderedDiagnostic>) => Tally;
685
- /**
686
- * K-7/K-8's two lowest tiers: `2` when any conformance error is present, else
687
- * `1` when any lint OR profile error is present, else `0`. Warnings and info
688
- * never move it. `130`, `64` and `3` are set elsewhere — by the runtime's
689
- * interrupt branch, by the `ShowHelp` remap in `bin.ts`, and by the typed
690
- * errors' own `[Runtime.errorExitCode]` — so this function returns only
691
- * `0 | 1 | 2`.
692
- *
693
- * @public
694
- */
695
- export declare const forDiagnostics: (diagnostics: ReadonlyArray<RenderedDiagnostic>) => 0 | 1 | 2;
696
- //#endregion
697
81
  //#region src/render/human.d.ts
698
82
  /** The counts the summary line reports. @public */
699
83
  interface Counts {
@@ -735,137 +119,7 @@ export declare const human: (diagnostics: ReadonlyArray<RenderedDiagnostic>, opt
735
119
  */
736
120
  export declare const summary: (counts: Counts, root: string) => string;
737
121
  //#endregion
738
- //#region src/render/json.d.ts
739
- /** One entry of the `diagnostics` array (K-21). @public */
740
- export declare const JsonDiagnostic: Schema.Struct<{
741
- readonly source: Schema.Literals<readonly ["core.conformance", "core.lint", "profile"]>;
742
- readonly file: Schema.String;
743
- readonly code: Schema.String;
744
- readonly severity: Schema.Literals<readonly ["error", "warning", "info"]>;
745
- readonly message: Schema.String;
746
- readonly range: Schema.optionalKey<typeof DiagnosticRange>;
747
- }>;
748
- /** @public */
749
- export type JsonDiagnostic = typeof JsonDiagnostic.Type;
750
- /** @public */
751
- export declare const JsonSummary: Schema.Struct<{
752
- readonly conformance_errors: Schema.Number;
753
- readonly lint_errors: Schema.Number;
754
- readonly lint_warnings: Schema.Number;
755
- readonly lint_info: Schema.Number;
756
- readonly profile_errors: Schema.Number;
757
- readonly concepts: Schema.Number;
758
- }>;
759
- /** @public */
760
- export type JsonSummary = typeof JsonSummary.Type;
761
- /**
762
- * K-21's success envelope, snake_case. `exit_code` is `0 | 1 | 2` only: an
763
- * infrastructure failure never produces this envelope, it produces the
764
- * `JsonErrorEnvelope` (K-22).
765
- *
766
- * @public
767
- */
768
- export declare const JsonEnvelope: Schema.Struct<{
769
- readonly schema: Schema.Literal<1>;
770
- readonly okfit_version: Schema.String;
771
- readonly okf_version: Schema.String;
772
- readonly root: Schema.String;
773
- readonly profile: Schema.NullOr<Schema.String>;
774
- readonly exit_code: Schema.Literals<readonly [0, 1, 2]>;
775
- readonly summary: Schema.Struct<{
776
- readonly conformance_errors: Schema.Number;
777
- readonly lint_errors: Schema.Number;
778
- readonly lint_warnings: Schema.Number;
779
- readonly lint_info: Schema.Number;
780
- readonly profile_errors: Schema.Number;
781
- readonly concepts: Schema.Number;
782
- }>;
783
- readonly diagnostics: Schema.$Array<Schema.Struct<{
784
- readonly source: Schema.Literals<readonly ["core.conformance", "core.lint", "profile"]>;
785
- readonly file: Schema.String;
786
- readonly code: Schema.String;
787
- readonly severity: Schema.Literals<readonly ["error", "warning", "info"]>;
788
- readonly message: Schema.String;
789
- readonly range: Schema.optionalKey<typeof DiagnosticRange>;
790
- }>>;
791
- }>;
792
- /** @public */
793
- export type JsonEnvelope = typeof JsonEnvelope.Type;
794
- /** K-22's envelope: the ONLY thing stdout carries under `--format json` on an exit-3 failure. @public */
795
- export declare const JsonErrorEnvelope: Schema.Struct<{
796
- readonly schema: Schema.Literal<1>;
797
- readonly okfit_version: Schema.String;
798
- readonly exit_code: Schema.Literal<3>;
799
- readonly error: Schema.Struct<{
800
- readonly tag: Schema.String;
801
- readonly message: Schema.String;
802
- }>;
803
- }>;
804
- /** @public */
805
- export type JsonErrorEnvelope = typeof JsonErrorEnvelope.Type;
806
- /**
807
- * Build the success envelope. `diagnostics` is sorted here with the same
808
- * `sort` the human renderer uses (K-21's "diagnostics are in the K-17
809
- * order"); `range` passes through as core computed it, zero-based.
810
- *
811
- * The value returned is in `Type` form (its `range`s are `DiagnosticRange`
812
- * instances). What stdout carries is `Schema.encodeSync(JsonEnvelope)` of it,
813
- * `JSON.stringify`-ed — one document, no trailing text.
814
- *
815
- * @public
816
- */
817
- export declare const json: (input: {
818
- readonly okfitVersion: string;
819
- readonly okfVersion: string;
820
- readonly root: string;
821
- readonly profile: string | null;
822
- readonly exitCode: 0 | 1 | 2;
823
- readonly concepts: number;
824
- readonly diagnostics: ReadonlyArray<RenderedDiagnostic>;
825
- }) => JsonEnvelope;
826
- /** K-22. `tag` is the error's `_tag` when it has one, else its constructor name. @public */
827
- export declare const jsonError: (error: unknown, okfitVersion: string) => JsonErrorEnvelope;
828
- //#endregion
829
122
  //#region src/render/verify.d.ts
830
- /**
831
- * V-11's success envelope, schema 1, snake_case — the same convention as
832
- * `render/json.ts`'s `JsonEnvelope`. Identical in shape for a dry run,
833
- * which sets `dry_run: true` and still exits 0. There is no content tier,
834
- * so `exit_code` is the literal `0`; a failure produces K-22's
835
- * `JsonErrorEnvelope` instead, unchanged.
836
- *
837
- * @public
838
- */
839
- export declare const VerifyEnvelope: Schema.Struct<{
840
- readonly schema: Schema.Literal<1>;
841
- readonly okfit_version: Schema.String;
842
- readonly id: Schema.String;
843
- readonly path: Schema.String;
844
- readonly verified: Schema.Struct<{
845
- readonly by: Schema.String;
846
- readonly at: Schema.String;
847
- }>;
848
- readonly dry_run: Schema.Boolean;
849
- readonly exit_code: Schema.Literal<0>;
850
- }>;
851
- /** @public */
852
- export type VerifyEnvelope = typeof VerifyEnvelope.Type;
853
- /**
854
- * `path` is already the display form — `displayRoot(cwd, bundle.root, path)`
855
- * joined to the bundle-relative `concept.path` — because `LoadedConcept.path`
856
- * alone would print `decisions/cli-exit-codes.md`, not
857
- * `okf/decisions/cli-exit-codes.md` (contract §12 note 5).
858
- *
859
- * @public
860
- */
861
- export declare const verifyEnvelope: (input: {
862
- readonly okfitVersion: string;
863
- readonly id: string;
864
- readonly path: string;
865
- readonly by: string;
866
- readonly at: string;
867
- readonly dryRun: boolean;
868
- }) => VerifyEnvelope;
869
123
  /** @public */
870
124
  interface VerifyLines {
871
125
  readonly id: string;
@@ -892,13 +146,15 @@ export declare const humanVerify: (input: VerifyLines) => ReadonlyArray<string>;
892
146
  //#endregion
893
147
  //#region src/version.d.ts
894
148
  /**
895
- * The version string reported by `okfit --version`, read from the package's
896
- * own manifest (K-32) so a release can never desync from the printed
897
- * version. Consumed by `bin.ts` only.
149
+ * The version string reported by `okfit --version`. `@savvy-web/bundler`
150
+ * replaces `process.env.__PACKAGE_VERSION__` with this package's own
151
+ * version at build time (K-32), so a release can never desync from the
152
+ * printed version. `"0.0.0"` is the unbuilt-source fallback and reads as
153
+ * dev mode.
898
154
  *
899
155
  * @public
900
156
  */
901
157
  export declare const CLI_VERSION: string;
902
158
  //#endregion
903
- export type { ConfigReadError, ContextResult, ContextRunOptions, Counts, DiagnosticSource, DiscoveredConfig, RenderedDiagnostic, ResolveProjectConfigInput, ResolvedProjectConfig, RunOptions, RunResult, ScaffoldFile, ScaffoldOptions, Tally, VerifyLines };
159
+ export type { Counts, VerifyLines };
904
160
  //# sourceMappingURL=index.d.ts.map