@okfit/cli 0.2.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/bin/okfit.js CHANGED
@@ -1,14 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { renderFailure } from "../errors.js";
3
- import { CLI_VERSION } from "../version.js";
4
- import { Now } from "../validate/run.js";
5
- import { rootCommand } from "../commands/root.js";
6
- import { Command } from "effect/unstable/cli";
7
- import { DateTime, Effect, Layer, Option } from "effect";
8
- import { CliLogger, CliRuntime } from "@effected/cli";
9
- import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
10
- import * as NodeServices from "@effect/platform-node/NodeServices";
11
- import { AppDirs, Xdg } from "@effected/xdg";
2
+ import { main } from "../main.js";
12
3
 
13
4
  //#region src/bin.ts
14
5
  /**
@@ -16,47 +7,7 @@ import { AppDirs, Xdg } from "@effected/xdg";
16
7
  *
17
8
  * @packageDocumentation
18
9
  */
19
- /**
20
- * K-9: `AppConfig.layer` only, built by Group B's `config/layer.ts` —
21
- * `Xdg` and `AppDirs` are provided once, here, for both commands; no
22
- * `Store`, no `Cache`, so no `store.db`/`cache.db` is ever created.
23
- *
24
- * `AppDirs.layer(options)` requires `Xdg | FileSystem | Path`
25
- * (`XDG/index.d.ts:320`), so `Layer.provide(Xdg.layer)` alone does not close
26
- * it: `Layer.provideMerge(NodeServices.layer)` supplies `FileSystem`/`Path`
27
- * to both members and keeps every service in the output. `NodeServices.layer`
28
- * provides `ChildProcessSpawner | Crypto | FileSystem | Path | Stdio |
29
- * Terminal`, a superset of `Command.Environment`.
30
- *
31
- * `Xdg.layer` fails with `XdgEnvError` when `HOME` is unset (K-13). That
32
- * error reaches `reportFailures` and takes its `exitCode: 3` fallback, with
33
- * no special case anywhere — but only because `Effect.provide(PlatformLayer)`
34
- * is applied INSIDE the region `CliRuntime.reportFailures` wraps, below.
35
- * `@effected/cli`'s own doc example provides its layer after
36
- * `reportFailures`; doing that here would let a failure while building this
37
- * layer (an unset `HOME`, say) escape reportFailures entirely and fall to
38
- * `NodeRuntime.runMain`'s own fatal-error path — a stack trace on stdout and
39
- * exit `1`, not the rendered `exitCode: 3` this module promises.
40
- */
41
- const PlatformLayer = Layer.mergeAll(Xdg.layer, AppDirs.layer({ namespace: "okfit" }).pipe(Layer.provide(Xdg.layer))).pipe(Layer.provideMerge(NodeServices.layer));
42
- /**
43
- * K-47: an ISO-8601 `OKFIT_NOW` when set, else the wall clock. A documented
44
- * test hook, not user-facing. Resolved exactly once, here, and provided to
45
- * the whole command tree through the `Now` tag so no command handler ever
46
- * reads `process.env["OKFIT_NOW"]` itself.
47
- */
48
- const nowEffect = Option.fromNullishOr(process.env.OKFIT_NOW).pipe(Option.flatMap((iso) => DateTime.make(iso)), Option.match({
49
- onNone: () => DateTime.now,
50
- onSome: Effect.succeed
51
- }));
52
- const program = Effect.gen(function* () {
53
- const now = yield* nowEffect;
54
- return yield* Command.run(rootCommand, { version: CLI_VERSION }).pipe(Effect.provideService(Now, now), Effect.catchTag("ShowHelp", (help) => Effect.fail(CliRuntime.reported(help, help.errors.length > 0 ? 64 : 0))));
55
- }).pipe(Effect.provide(PlatformLayer), CliRuntime.reportFailures({
56
- exitCode: 3,
57
- render: renderFailure
58
- }));
59
- NodeRuntime.runMain(program.pipe(Effect.provide(CliLogger.layer())));
10
+ main();
60
11
 
61
12
  //#endregion
62
13
  export { };
@@ -1,11 +1,8 @@
1
- import { provideConfig } from "../config/layer.js";
2
- import { resolveProjectConfig } from "../config/resolve.js";
3
- import { runContext } from "../context/run.js";
4
1
  import { setExitCode } from "../internal/exit.js";
5
- import { ContextEnvelope, contextEnvelope, humanContext } from "../render/context.js";
6
- import { jsonError } from "../render/json.js";
2
+ import { humanContext } from "../render/context.js";
7
3
  import { CLI_VERSION } from "../version.js";
8
4
  import { Argument, Command, Flag } from "effect/unstable/cli";
5
+ import { ContextEnvelope, contextEnvelope, jsonError, provideConfig, resolveProjectConfig, runContext } from "@okfit/engine";
9
6
  import { Console, Effect, Option, Schema } from "effect";
10
7
 
11
8
  //#region src/commands/context.ts
@@ -20,7 +17,7 @@ const formatFlag = Flag.choice("format", ["human", "json"]).pipe(Flag.withDefaul
20
17
  *
21
18
  * Handler order fixed by the contract (§8.3): steps 1–7 are
22
19
  * `validateCommand`'s handler in substance (both now share
23
- * `config/resolve.ts#resolveProjectConfig` — A4) — stat `--config` (K-1) via
20
+ * `@okfit/engine`'s `resolveProjectConfig` — A4) — stat `--config` (K-1) via
24
21
  * `provideConfig`, discover (`OkfitConfigFile.discover`), resolve the
25
22
  * profile with the K-4 warning, merge `DEFAULTS < profile < file` (D-28),
26
23
  * warn on an `okf_version` mismatch (K-15), resolve the project and bundle
package/commands/init.js CHANGED
@@ -1,19 +1,13 @@
1
- import { InitOverwriteError } from "../errors.js";
2
- import { provideConfig } from "../config/layer.js";
3
- import { resolveBundleRoot, resolveProjectRoot } from "../config/anchor.js";
4
1
  import { setExitCode } from "../internal/exit.js";
5
- import { forDiagnostics } from "../render/exit.js";
6
- import { collect } from "../render/sort.js";
7
- import { CONFIG_RELATIVE_PATH, SCHEMA_DIRECTIVE, configValue, files, targetPaths } from "../init/scaffold.js";
8
2
  import { useColor } from "../internal/tty.js";
9
3
  import { displayRoot, human, summary } from "../render/human.js";
10
- import { Now, run } from "../validate/run.js";
11
4
  import { Argument, Command, Flag } from "effect/unstable/cli";
5
+ import { CONFIG_RELATIVE_PATH, InitOverwriteError, Now, SCHEMA_DIRECTIVE, collect, configValue, files, forDiagnostics, provideConfig, resolveBundleRoot, resolveProjectRoot, run, targetPaths } from "@okfit/engine";
12
6
  import { Console, DateTime, Effect, FileSystem, Layer, Option, Path, Schema } from "effect";
13
7
  import { TomlCodec } from "@effected/config-file";
8
+ import { Git } from "@effected/git";
14
9
  import { OKF_SPEC_VERSION, OkfitConfig, OkfitConfigFile } from "@okfit/core";
15
10
  import { GitHistory, Profiles } from "@okfit/profiles";
16
- import { Git } from "@effected/git";
17
11
 
18
12
  //#region src/commands/init.ts
19
13
  /**
@@ -74,7 +68,7 @@ const countsOf = (diagnostics, concepts) => ({
74
68
  * fileConfig)`, `profileConfig` falling back to `NO_PROFILE_CONFIG` when
75
69
  * no profile resolved.
76
70
  * 6. `merged.okf_version !== OKF_SPEC_VERSION` warns (K-15).
77
- * 7. `projectRoot`/`bundleRoot` via `config/anchor.ts`; `now = yield* Now`;
71
+ * 7. `projectRoot`/`bundleRoot` via `@okfit/engine`'s `config/anchor.ts`; `now = yield* Now`;
78
72
  * `layout` falls back to `Profiles.softwareProject.layout` when no
79
73
  * profile resolved (this file's own decision 2 above — `Layout` has no
80
74
  * `DEFAULTS` equivalent).
package/commands/sync.js CHANGED
@@ -1,15 +1,12 @@
1
- import { provideConfig } from "../config/layer.js";
2
- import { resolveProjectConfig } from "../config/resolve.js";
3
1
  import { setExitCode } from "../internal/exit.js";
4
- import { jsonError } from "../render/json.js";
5
2
  import { CLI_VERSION } from "../version.js";
6
3
  import { displayRoot } from "../render/human.js";
7
- import { runSync } from "../sync/run.js";
8
- import { SyncEnvelope, humanSync, syncEnvelope } from "../render/sync.js";
4
+ import { humanSync } from "../render/sync.js";
9
5
  import { Argument, Command, Flag } from "effect/unstable/cli";
6
+ import { SyncEnvelope, jsonError, provideConfig, resolveProjectConfig, runSync, syncEnvelope } from "@okfit/engine";
10
7
  import { Console, Effect, Layer, Option, Path, Schema } from "effect";
11
- import { GitHistory } from "@okfit/profiles";
12
8
  import { Git } from "@effected/git";
9
+ import { GitHistory } from "@okfit/profiles";
13
10
 
14
11
  //#region src/commands/sync.ts
15
12
  /** K-2: `[path]` is the PROJECT root, byte-identical to validate/init/context/verify's. */
@@ -1,18 +1,13 @@
1
- import { provideConfig } from "../config/layer.js";
2
- import { resolveProjectConfig } from "../config/resolve.js";
3
1
  import { setExitCode } from "../internal/exit.js";
4
- import { forDiagnostics } from "../render/exit.js";
5
- import { collect } from "../render/sort.js";
6
- import { JsonEnvelope, json, jsonError } from "../render/json.js";
7
2
  import { CLI_VERSION } from "../version.js";
8
3
  import { useColor } from "../internal/tty.js";
9
4
  import { displayRoot, human, summary } from "../render/human.js";
10
- import { Now, run } from "../validate/run.js";
11
5
  import { Argument, Command, Flag } from "effect/unstable/cli";
6
+ import { JsonEnvelope, Now, collect, forDiagnostics, json, jsonError, provideConfig, resolveProjectConfig, run } from "@okfit/engine";
12
7
  import { Console, Effect, Layer, Option, Path, Schema } from "effect";
8
+ import { Git } from "@effected/git";
13
9
  import { OKF_SPEC_VERSION } from "@okfit/core";
14
10
  import { GitHistory } from "@okfit/profiles";
15
- import { Git } from "@effected/git";
16
11
 
17
12
  //#region src/commands/validate.ts
18
13
  /** `[path]` is the PROJECT root (K-2), never the bundle root. Absolute at parse time (K-50). */
@@ -30,7 +25,7 @@ const skipProvenanceFlag = Flag.boolean("skip-provenance").pipe(Flag.withDefault
30
25
  * stat `--config` (K-1) via `provideConfig`, discover (`OkfitConfigFile.discover`),
31
26
  * resolve the profile with the K-4 warning, merge `DEFAULTS < profile < file`
32
27
  * (D-28), warn on an `okf_version` mismatch (K-15), resolve the project and
33
- * bundle roots (K-12), run (`validate/run.ts#run`), collect and sort the
28
+ * bundle roots (K-12), run (`@okfit/engine`'s `validate/run.ts#run`), collect and sort the
34
29
  * diagnostics, render per `--format` (K-18, K-20 to K-22), and set the exit
35
30
  * code without failing the Effect (K-7, K-8).
36
31
  *
@@ -1,16 +1,12 @@
1
- import { provideConfig } from "../config/layer.js";
2
- import { resolveProjectConfig } from "../config/resolve.js";
3
1
  import { setExitCode } from "../internal/exit.js";
4
- import { jsonError } from "../render/json.js";
5
2
  import { CLI_VERSION } from "../version.js";
6
3
  import { displayRoot } from "../render/human.js";
7
- import { Now } from "../validate/run.js";
8
- import { VerifyEnvelope, humanVerify, verifyEnvelope } from "../render/verify.js";
9
- import { runVerify } from "../verify/run.js";
4
+ import { humanVerify } from "../render/verify.js";
10
5
  import { Argument, Command, Flag } from "effect/unstable/cli";
6
+ import { Now, VerifyEnvelope, jsonError, provideConfig, resolveProjectConfig, runVerify, verifyEnvelope } from "@okfit/engine";
11
7
  import { Console, DateTime, Effect, Option, Path, Schema } from "effect";
12
- import { Timestamp } from "@okfit/core";
13
8
  import { Git } from "@effected/git";
9
+ import { Timestamp } from "@okfit/core";
14
10
 
15
11
  //#region src/commands/verify.ts
16
12
  /** V-6: tolerant id, normalised through `ConceptId.normalize`; never `Argument.path`. */
package/errors.js CHANGED
@@ -1,111 +1,8 @@
1
- import { Runtime, Schema } from "effect";
1
+ import { ConfigMalformedError, ConfigPathNotFoundError, InitOverwriteError, VerifyConceptNotFoundError, VerifyUnsupportedFrontmatterError } from "@okfit/engine";
2
2
  import { ConfigIssueRenderer } from "@effected/cli";
3
3
 
4
4
  //#region src/errors.ts
5
- /**
6
- * `--config <path>` named a path that does not exist. Every `ConfigResolver`
7
- * has a `never` error channel and `explicitPath` absorbs a missing target
8
- * into `Option.none()`, so a bad `--config` would otherwise fall through to
9
- * the XDG file silently. The CLI checks it itself before building any layer
10
- * (K-1, spec 4.1).
11
- *
12
- * @public
13
- */
14
- var ConfigPathNotFoundError = class extends Schema.TaggedError()("ConfigPathNotFoundError", { path: Schema.String }) {
15
- [Runtime.errorExitCode] = 3;
16
- get message() {
17
- return `config path not found: ${this.path}`;
18
- }
19
- };
20
- /**
21
- * `okfit init` found one or more of its target paths already present (K-28).
22
- * Carries the whole conflicting-path list so the renderer prints every one.
23
- * `paths` are absolute; `renderFailure` relativises them to `cwd` (K-51).
24
- *
25
- * @public
26
- */
27
- var InitOverwriteError = class extends Schema.TaggedError()("InitOverwriteError", {
28
- paths: Schema.Array(Schema.String),
29
- cwd: Schema.String
30
- }) {
31
- [Runtime.errorExitCode] = 3;
32
- get message() {
33
- return "refusing to overwrite existing files";
34
- }
35
- };
36
- /**
37
- * V-9: `<id>` did not resolve to a verifiable concept. `reason` is
38
- * `"not-a-concept"` (no such file, or an id that normalises to nothing),
39
- * `"reserved"` (the id names `index.md` or `log.md`), or `"undecodable"`
40
- * (a file exists but `bundle.diagnostics` names it — `diagnosticCode`
41
- * carries which). `root` is the absolute bundle root, kept OFF `message`
42
- * so K-51's relativisation rule has nothing to apply to and the human
43
- * line and the JSON envelope's `message` are identical.
44
- *
45
- * @public
46
- */
47
- var VerifyConceptNotFoundError = class extends Schema.TaggedError()("VerifyConceptNotFoundError", {
48
- id: Schema.String,
49
- root: Schema.String,
50
- reason: Schema.Literals([
51
- "not-a-concept",
52
- "reserved",
53
- "undecodable"
54
- ]),
55
- diagnosticCode: Schema.optionalKey(Schema.String)
56
- }) {
57
- [Runtime.errorExitCode] = 3;
58
- get message() {
59
- const detail = this.diagnosticCode === void 0 ? this.reason : `${this.reason}: ${this.diagnosticCode}`;
60
- return `no concept "${this.id}" in this bundle (${detail})`;
61
- }
62
- };
63
- /**
64
- * V-14: fail closed on a `verified` shape the classifier does not name.
65
- * `shape` is one of `"alias"`, `"merge-key"`, `"scalar"`, `"empty"` (and,
66
- * defensively, `"no-frontmatter"` or `"not-a-mapping"`, neither reachable
67
- * for a concept that reached `bundle.concepts`). The file is never opened
68
- * for writing when this is raised.
69
- *
70
- * @public
71
- */
72
- var VerifyUnsupportedFrontmatterError = class extends Schema.TaggedError()("VerifyUnsupportedFrontmatterError", {
73
- id: Schema.String,
74
- shape: Schema.String
75
- }) {
76
- [Runtime.errorExitCode] = 3;
77
- get message() {
78
- return `"${this.id}"'s verified value is a shape okfit verify cannot edit (${this.shape}); edit it by hand`;
79
- }
80
- };
81
5
  const hasTag = (error, tag) => typeof error === "object" && error !== null && "_tag" in error && error._tag === tag;
82
- /** The error's `message` when it has one as a string, else `String(error)`. */
83
- const messageOf = (error) => {
84
- if (typeof error === "object" && error !== null && "message" in error) {
85
- const message = error.message;
86
- if (typeof message === "string") return message;
87
- }
88
- return String(error);
89
- };
90
- /**
91
- * A config file at a KNOWN path failed to parse or validate (K-46's own
92
- * intent — "each class' message already names the offending path" does not
93
- * hold for `@effected/config-file`'s `ConfigCodecError`, which carries no
94
- * `path` field at all; this wraps it, and `ConfigValidationError`, with the
95
- * path the caller already knows). `cause` is the original config-file error,
96
- * preserved structurally, never stringified early.
97
- *
98
- * @public
99
- */
100
- var ConfigMalformedError = class extends Schema.TaggedError()("ConfigMalformedError", {
101
- path: Schema.String,
102
- cause: Schema.Defect()
103
- }) {
104
- [Runtime.errorExitCode] = 3;
105
- get message() {
106
- return `malformed config ${this.path}: ${messageOf(this.cause)}`;
107
- }
108
- };
109
6
  /** `path` relative to `cwd` when it is under it, else the absolute path unchanged (K-51). */
110
7
  const relativeToCwd = (path, cwd) => {
111
8
  if (path === cwd) return ".";
@@ -170,4 +67,4 @@ const renderFailure = (error) => {
170
67
  };
171
68
 
172
69
  //#endregion
173
- export { ConfigMalformedError, ConfigPathNotFoundError, InitOverwriteError, VerifyConceptNotFoundError, VerifyUnsupportedFrontmatterError, renderFailure };
70
+ export { renderFailure };