packages feed

okf-cli 0.8.0.0 → 0.9.0.0

raw patch · 5 files changed

+96/−25 lines, 5 filesdep ~okf-corePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: okf-core

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -7,6 +7,26 @@  ## [Unreleased] +## [0.9.0.0] - 2026-09-13++### Added++- `okf profile show` renders optional profile and type guidance as stable+  multiline blocks, and `--json` exposes the same string-or-null fields.+  `okf profile document` renders profile-wide guidance before additive+  type-specific guidance in Markdown bodies and never executes the prose.++### Changed++- **Breaking:** requires the coordinated `okf-core` release whose public+  profile schema and Haskell records add `guidance`; older descriptor values+  remain accepted by okf-core's frozen compatibility decoder.+- Requires `okf-core ^>=0.9.0.0`.+- `okf profile list` and `okf profile sources` report the built-in+  `mori://shinzui/okf-profiles` v0.14.0 catalogue (thirteen profiles, up from+  ten), including `assurance.reviews`, `assurance.failureModes`, and+  `documentation.userDocumentation`.+ ## [0.8.0.0] - 2026-08-19  ### Added
help/profiles.md view
@@ -140,9 +140,16 @@   leaves you to compose them. Recommended keys carry a bullet saying they are   checked only under --strict. +  Profile and type rules may also carry multiline `guidance`. The root page+  renders profile guidance. Every applicable type page renders a Guidance+  section with Profile-wide prose first and Type-specific prose second; a type+  rule adds to, never replaces, the universal instruction. Blank or absent+  guidance creates no section, and guidance remains body Markdown rather than+  generated frontmatter.+   The `description` prose you write on the profile, on a type rule, and on-  each key is what fills the generated pages. A profile with no descriptions-  still generates, with synthesized summaries.+  each key identifies what it documents. A profile with no descriptions still+  generates, with synthesized summaries.    The output is an ordinary OKF bundle, so okf validate, okf graph, and   okf show all work on it. Generation never reads the clock, so regenerating@@ -179,14 +186,27 @@   what a generated documentation bundle looks like, and   examples/postgresql-profile/ as a committed worked example. -DESCRIPTIONS+DESCRIPTIONS, GUIDANCE, AND RULES    A profile may document itself: one description for the profile as a whole,   one per required, recommended, or optional frontmatter key, and one per type   rule.-  Descriptions are prose for humans -- okf never checks one against a bundle-  and none can produce a deviation.+  A description says what the profile, type, or key is and stays concise enough+  for listings and generated frontmatter. +  `guidance : Optional Text` is a separate multiline Markdown field on the+  profile and every type rule. It says how an author should work. Profile+  guidance applies to every type, and matching type guidance is added after it.+  `okf profile show` prints each block after its description, preserving+  internal lines; absent or whitespace-only values print `guidance: (none)`.+  Full show JSON includes string-or-null guidance fields, while compact profile+  listings omit them.++  Structured rules say what okf can actually check. Descriptions and guidance+  are prose for humans and tools -- neither can produce a deviation. okf never+  runs a command from guidance, invokes Hurl, queries an event stream, or+  executes a fenced code block.+   `okf profile list` shows the profile's own description on the indented line   below its identity, reading "-" when it has none. `okf profile show` prints   the profile description under the name, one "  - key: prose" line per@@ -196,8 +216,9 @@      profile: schemas/sales/tables/orders: missing profile-required field: title (Human-readable name of the object.) -  Descriptions are optional and additive. A descriptor written before they-  existed loads unchanged and simply shows none; nothing needs migrating. See+  Descriptions and guidance are optional and additive. A descriptor written+  before either schema generation loads through its frozen compatibility+  decoder and simply shows none; nothing needs migrating. See   docs/user/profiles.md for how to add them to a descriptor you already have.  TYPE-AWARE FRONTMATTER@@ -484,7 +505,7 @@   runs are offline. Pass --registry with a local checkout to be offline   throughout. -  The built-in pin currently targets v0.10.0 and publishes ten OKF 0.2 profiles+  The built-in pin currently targets v0.14.0 and publishes thirteen OKF 0.2 profiles   with descriptions. `okf profile sources` reports that version without network   access. Pass --check-latest to that command for an explicit upstream tag   comparison; a failed optional check is reported but does not change the source
okf-cli.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.4 name:               okf-cli-version:            0.8.0.0+version:            0.9.0.0 synopsis:           Command-line interface for Open Knowledge Format bundles description:   okf-cli provides the @okf@ executable for working with Open Knowledge Format@@ -71,7 +71,7 @@     , generic-lens          >=2.2      && <2.4     , githash               ^>=0.1     , lens                  ^>=5.3-    , okf-core              ^>=0.8.0.0+    , okf-core              ^>=0.9.0.0     , optparse-applicative  >=0.18     && <0.20     , process               >=1.6      && <1.7     , text                  ^>=2.1@@ -88,7 +88,7 @@     , directory     , filepath     , okf-cli-    , okf-core              ^>=0.8.0.0+    , okf-core              ^>=0.9.0.0     , optparse-applicative  >=0.18     , temporary     , text                  ^>=2.1
src/Okf/Cli.hs view
@@ -1861,6 +1861,7 @@   ProfileSpec     { name,       description,+      guidance,       okfVersion,       frontmatter,       allowUnknownTypes,@@ -1871,13 +1872,15 @@     } =     [ "export: " <> displayExport exportPath,       "name: " <> name,-      "description: " <> renderOptional description,-      "okfVersion: " <> okfVersion,-      "requireBundleVersion: " <> renderOptional requireBundleVersion,-      "allowUnknownTypes: " <> renderFlag allowUnknownTypes,-      "allowUnknownFields: " <> renderFlag allowUnknownFields,-      "idField: " <> renderOptional idField+      "description: " <> renderOptional description     ]+      <> renderGuidance "" guidance+      <> [ "okfVersion: " <> okfVersion,+           "requireBundleVersion: " <> renderOptional requireBundleVersion,+           "allowUnknownTypes: " <> renderFlag allowUnknownTypes,+           "allowUnknownFields: " <> renderFlag allowUnknownFields,+           "idField: " <> renderOptional idField+         ]       <> renderPresenceLists "" frontmatter       <> concatMap renderTypeRule typeRules     where@@ -1943,6 +1946,7 @@         TypeRule           { type_ = ruleType,             description = ruleDescription,+            guidance = ruleGuidance,             frontmatter = typeFrontmatter,             pathPattern,             resourceScheme,@@ -1954,6 +1958,7 @@             "type: " <> ruleType,             "  description: " <> renderOptional ruleDescription           ]+            <> renderGuidance "  " ruleGuidance             <> renderPresenceLists "  " typeFrontmatter             <> [ "  pathPattern: " <> renderOptional pathPattern,                  "  resourceScheme: " <> renderOptional resourceScheme,@@ -1964,6 +1969,13 @@        renderFlag True = "true"       renderFlag False = "false"+      renderGuidance indent prose =+        case trimOuterBlankLines (maybe [] Text.lines prose) of+          [] -> [indent <> "guidance: (none)"]+          proseLines ->+            (indent <> "guidance:") : map (indent <>) (map ("  " <>) proseLines)+      trimOuterBlankLines = List.dropWhileEnd isBlank . dropWhile isBlank+      isBlank = Text.null . Text.strip       renderOptional = fromMaybe "(none)"       renderList [] = "(none)"       renderList values = Text.intercalate ", " values
test/Main.hs view
@@ -968,18 +968,18 @@   let rendered = renderProfileSourceResolution sampleProfileSourceResolutions FreshnessNotChecked    in all         (`Text.isInfixOf` rendered)-        [ "okf-profiles v0.10.0 (pinned)",+        [ "okf-profiles v0.14.0 (pinned)",           "[built-in default]",           "[env: OKF_PROFILE_REGISTRIES]",           "failed (import-failure)",-          "Pinned catalogue: okf-profiles v0.10.0",+          "Pinned catalogue: okf-profiles v0.14.0",           "1. --registry flag (repeatable)",           "lookup fails closed."         ]  testProfileSourcesJsonShape :: Bool testProfileSourcesJsonShape =-  profileSourcesJson sampleProfileSourceResolutions (FreshnessOutdated "v0.10.0" "v0.11.0")+  profileSourcesJson sampleProfileSourceResolutions (FreshnessOutdated "v0.14.0" "v0.15.0")     == Aeson.object       [ "sources"           Aeson..= [ Aeson.object@@ -1009,13 +1009,13 @@                              ]                        ]                    ],-        "pinnedVersion" Aeson..= Just ("v0.10.0" :: Text.Text),+        "pinnedVersion" Aeson..= Just ("v0.14.0" :: Text.Text),         "freshness"           Aeson..= Aeson.object             [ "status" Aeson..= ("outdated" :: Text.Text),-              "pinnedVersion" Aeson..= ("v0.10.0" :: Text.Text),-              "latestVersion" Aeson..= ("v0.11.0" :: Text.Text),-              "refreshCommand" Aeson..= ("scripts/refresh-default-registry.sh v0.11.0" :: Text.Text)+              "pinnedVersion" Aeson..= ("v0.14.0" :: Text.Text),+              "latestVersion" Aeson..= ("v0.15.0" :: Text.Text),+              "refreshCommand" Aeson..= ("scripts/refresh-default-registry.sh v0.15.0" :: Text.Text)             ],         "precedence" Aeson..= profileSourcePrecedenceFixture       ]@@ -1040,7 +1040,7 @@     && parseReleaseVersionTag "v0.9.3" == Just (ReleaseVersion 0 9 3)     && parseReleaseVersionTag "0.10.0" == Nothing     && parseReleaseVersionTag "v0.10" == Nothing-    && pinnedRegistryTag defaultRegistryReference == Just "v0.10.0"+    && pinnedRegistryTag defaultRegistryReference == Just "v0.14.0"     && latestReleaseTag       "aaa\trefs/tags/v0.9.3\nbbb\trefs/tags/not-a-version\nccc\trefs/tags/v0.10.0\n"       == Just "v0.10.0"@@ -1081,6 +1081,7 @@   ProfileSpec     { name = "shinzui-postgresql",       description = Nothing,+      guidance = Nothing,       okfVersion = "0.1",       frontmatter =         FrontmatterRules@@ -1096,6 +1097,7 @@         [ TypeRule             { type_ = "PostgreSQL Table",               description = Nothing,+              guidance = Nothing,               frontmatter = FrontmatterRules {required = [], recommended = [], optional = []},               pathPattern = Just "schemas/*/tables/*",               resourceScheme = Just "postgresql",@@ -1111,6 +1113,9 @@   ProfileSpec     { name = "decisions",       description = Just "How this team records architectural decisions.",+      guidance =+        Just+          "\nCapture the context and evidence for every decision.\n\nLink the implementation plan when one exists.\n",       okfVersion = "0.1",       frontmatter =         FrontmatterRules@@ -1155,6 +1160,7 @@         [ TypeRule             { type_ = "Decision Record",               description = Just "One accepted decision, never edited after acceptance.",+              guidance = Just "Explain the trade-offs.\n\nRecord follow-up work.",               frontmatter =                 FrontmatterRules                   { required = [FieldRule "owner" (Just "Person responsible for the decision.") [] Scalar (Just (DocumentHandle "USR")) Nothing Nothing Nothing Nothing Nothing Nothing],@@ -1186,6 +1192,7 @@   ProfileSpec     { name = "nested",       description = Nothing,+      guidance = Nothing,       okfVersion = "0.1",       frontmatter =         FrontmatterRules@@ -1253,6 +1260,7 @@   [ "export: (root)",     "name: nested",     "description: (none)",+    "guidance: (none)",     "okfVersion: 0.1",     "requireBundleVersion: (none)",     "allowUnknownTypes: true",@@ -1332,6 +1340,10 @@   [ "export: nested.decisions",     "name: decisions",     "description: How this team records architectural decisions.",+    "guidance:",+    "  Capture the context and evidence for every decision.",+    "  ",+    "  Link the implementation plan when one exists.",     "okfVersion: 0.1",     "requireBundleVersion: (none)",     "allowUnknownTypes: false",@@ -1373,6 +1385,10 @@     "",     "type: Decision Record",     "  description: One accepted decision, never edited after acceptance.",+    "  guidance:",+    "    Explain the trade-offs.",+    "    ",+    "    Record follow-up work.",     "  frontmatter.required:",     "    - owner: Person responsible for the decision.",     "      allowedValues: (any)",@@ -1421,6 +1437,7 @@   [ "export: (root)",     "name: shinzui-postgresql",     "description: (none)",+    "guidance: (none)",     "okfVersion: 0.1",     "requireBundleVersion: (none)",     "allowUnknownTypes: false",@@ -1452,6 +1469,7 @@     "",     "type: PostgreSQL Table",     "  description: (none)",+    "  guidance: (none)",     "  frontmatter.required: (none)",     "  frontmatter.recommended: (none)",     "  frontmatter.optional: (none)",