okforge 1.0.1

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.
Files changed (41) hide show
  1. package/.claude/skills/okf/README.md +141 -0
  2. package/.claude/skills/okf/SKILL.md +124 -0
  3. package/LICENSE +21 -0
  4. package/README.md +72 -0
  5. package/dist/cli.d.ts +3 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +109 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/commands/check_command.d.ts +15 -0
  10. package/dist/commands/check_command.d.ts.map +1 -0
  11. package/dist/commands/check_command.js +17 -0
  12. package/dist/commands/check_command.js.map +1 -0
  13. package/dist/commands/folders_command.d.ts +6 -0
  14. package/dist/commands/folders_command.d.ts.map +1 -0
  15. package/dist/commands/folders_command.js +9 -0
  16. package/dist/commands/folders_command.js.map +1 -0
  17. package/dist/commands/install_command.d.ts +25 -0
  18. package/dist/commands/install_command.d.ts.map +1 -0
  19. package/dist/commands/install_command.js +45 -0
  20. package/dist/commands/install_command.js.map +1 -0
  21. package/dist/commands/map_command.d.ts +6 -0
  22. package/dist/commands/map_command.d.ts.map +1 -0
  23. package/dist/commands/map_command.js +16 -0
  24. package/dist/commands/map_command.js.map +1 -0
  25. package/dist/commands/nudge_command.d.ts +32 -0
  26. package/dist/commands/nudge_command.d.ts.map +1 -0
  27. package/dist/commands/nudge_command.js +72 -0
  28. package/dist/commands/nudge_command.js.map +1 -0
  29. package/dist/commands/sources_command.d.ts +6 -0
  30. package/dist/commands/sources_command.d.ts.map +1 -0
  31. package/dist/commands/sources_command.js +13 -0
  32. package/dist/commands/sources_command.js.map +1 -0
  33. package/dist/commands/stale_command.d.ts +6 -0
  34. package/dist/commands/stale_command.d.ts.map +1 -0
  35. package/dist/commands/stale_command.js +9 -0
  36. package/dist/commands/stale_command.js.map +1 -0
  37. package/dist/misc/okf_store.d.ts +78 -0
  38. package/dist/misc/okf_store.d.ts.map +1 -0
  39. package/dist/misc/okf_store.js +261 -0
  40. package/dist/misc/okf_store.js.map +1 -0
  41. package/package.json +47 -0
@@ -0,0 +1,141 @@
1
+ # okf — Open Knowledge Format bundle skill
2
+
3
+ A Claude Code skill for maintaining the repository's Open Knowledge Format (OKF)
4
+ knowledge bundle under `okf/`. Spec:
5
+ https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md
6
+
7
+ OKF is an open, human- and agent-friendly format for **knowledge** — the
8
+ metadata, context, and curated insight that surrounds a system. A bundle is a
9
+ directory of plain markdown files: each concept document carries YAML
10
+ frontmatter with a required `type`, and reserved `index.md` / `log.md` files
11
+ provide listings and history. If you can `cat` a file you can read OKF; if you
12
+ can `git clone` a repo you can ship it.
13
+
14
+ This directory holds the skill. `SKILL.md` is the instruction file Claude loads;
15
+ this README is for humans browsing the repository.
16
+
17
+ ## Why a skill
18
+
19
+ The `okf/` bundle is **derived** from source — each folder is generated from
20
+ specific files, so when those files change the docs drift. The hard parts to
21
+ keep consistent are the OKF format, the folder-to-source mapping, and link
22
+ integrity. The skill keeps those uniform so you can focus on accurate prose.
23
+
24
+ ## What it does
25
+
26
+ Three modes, chosen from how you ask:
27
+
28
+ | You say | Mode | What happens |
29
+ |---|---|---|
30
+ | "set up okf", "create an OKF bundle", bundle missing | **scaffold** | Creates `.okforge.config.json`, `okf/index.md` (root, with `okf_version`), `okf/log.md`, the folders from the mapping, and refreshes each. |
31
+ | "the API changed, update okf", "refresh okf for X", "update the OKF docs" | **refresh** | Reads the current source for the affected folder(s) and regenerates only the docs whose source actually changed, grounded in what it read. |
32
+ | "check okf", "is the bundle conformant", "any dead links" | **check** | Runs the conformance and dead-link lint. |
33
+
34
+ Invoke it by asking Claude in plain language, or with `/okf`.
35
+
36
+ Regeneration is model-driven, so refresh is a **draft-then-review** loop: the
37
+ skill rewrites the affected docs, you review them, then commit. It will not
38
+ silently rewrite docs whose source did not change.
39
+
40
+ ## Automatic capture going forward
41
+
42
+ A companion `Stop` hook, `npx okforge nudge` (registered in
43
+ `.claude/settings.json`), reminds you when a session changed source that an OKF
44
+ folder documents but left `okf/` untouched. It is deliberately gentle:
45
+ non-blocking, at most once per session, and silent if you already touched
46
+ `okf/` that session. It reads the same mapping the skill uses (via
47
+ `npx okforge stale`), so the skill and the nudge never diverge.
48
+
49
+ ## Where the bundle lives
50
+
51
+ The bundle is the `okf/` directory at the repository root — a valid OKF bundle
52
+ is just a subdirectory of a larger repo, so there is no build step or manifest
53
+ beyond `okf_version` in the root `okf/index.md`. The folder-to-source mapping
54
+ lives next to it in `.okforge.config.json` at the project root.
55
+
56
+ ## The `okforge` CLI
57
+
58
+ The bundled [`okforge`](https://www.npmjs.com/package/okforge) CLI owns the
59
+ deterministic mechanics, run with `npx` (Node >= 20.12). The model writes the
60
+ prose; the CLI answers "what is each folder derived from?" and "is the bundle
61
+ still well-formed?".
62
+
63
+ | Command | Purpose |
64
+ |---|---|
65
+ | `npx okforge map [<dir>]` | Print the full folder-to-source mapping. |
66
+ | `npx okforge folders [<dir>]` | List the OKF concept folders. |
67
+ | `npx okforge sources <folder> [<dir>]` | Print the source paths a folder is derived from. |
68
+ | `npx okforge stale [<dir>]` | List folders whose source changed since HEAD while the folder itself was not edited. |
69
+ | `npx okforge check [<dir>]` | Conformance + dead-link lint; exits non-zero on problems. |
70
+ | `npx okforge nudge` | Stop-hook entry: read the hook payload on stdin and maybe remind. |
71
+
72
+ `<dir>` defaults to the current directory (the repository root). `check` verifies:
73
+ snake_case names only, every non-index `.md` has a non-empty frontmatter `type`,
74
+ sub-folder `index.md` files carry no frontmatter, and every bundle-relative `.md`
75
+ link resolves.
76
+
77
+ When developing in this repo you can run the source directly with
78
+ `npx tsx src/cli.ts <command>`, or via the npm script `npm run okforge -- <command>`.
79
+
80
+ ## The mapping: `.okforge.config.json`
81
+
82
+ okforge ships with **no** repository-specific paths. Each repo declares its own
83
+ folder-to-source mapping in `.okforge.config.json` at the project root:
84
+
85
+ ```json
86
+ {
87
+ "folders": {
88
+ "runtime_concepts": ["packages/foo/src/model/", "packages/foo/src/event/"],
89
+ "config_formats": ["packages/foo/data/schemas/thing.schema.json"]
90
+ }
91
+ }
92
+ ```
93
+
94
+ Each key is an OKF concept folder; each value is the list of source path prefixes
95
+ that folder is derived from. With no config present, `map`/`folders` are empty and
96
+ `stale` is a no-op; `check` still works, since it lints the bundle's markdown
97
+ alone. This is the only project-specific part — both the skill and the nudge read
98
+ it from here.
99
+
100
+ ## Layout
101
+
102
+ ```
103
+ .claude/skills/okf/
104
+ ├── SKILL.md instructions Claude loads
105
+ └── README.md this file
106
+
107
+ src/ the okforge CLI (mechanics)
108
+ ├── cli.ts Commander entry; wires the subcommands below
109
+ ├── misc/
110
+ │ └── okf_store.ts mapping load, stale detection, conformance lint
111
+ └── commands/
112
+ ├── map_command.ts print the folder-to-source mapping
113
+ ├── folders_command.ts list the concept folders
114
+ ├── sources_command.ts print a folder's source paths
115
+ ├── stale_command.ts folders whose source changed since HEAD
116
+ ├── check_command.ts conformance + dead-link lint
117
+ └── nudge_command.ts the Stop-hook nudge
118
+ ```
119
+
120
+ ## Conventions
121
+
122
+ - File and folder names are snake_case. No kebab-case, no spaces.
123
+ - Every non-index `.md` is a concept document: YAML frontmatter with a non-empty
124
+ `type`, then structural markdown (headings, lists, tables, code) using the
125
+ conventional `# Schema` / `# Examples` / `# Citations` sections where they
126
+ apply.
127
+ - `index.md` is reserved and carries no frontmatter — except the root
128
+ `okf/index.md`, which declares `okf_version: "0.1"` and `type: Bundle Index`.
129
+ - Cross-link concepts with bundle-relative absolute paths
130
+ (`/runtime_concepts/job_store.md`); cite real source files with repo-relative
131
+ paths (`../../packages/...`).
132
+ - Ground every claim in real source. Do not invent fields, routes, flags, or
133
+ states; if uncertain, omit.
134
+
135
+ ## Reusing this in another project
136
+
137
+ The skill is self-contained. Copy `.claude/skills/okf/`, register `npx okforge
138
+ nudge` as a `Stop` hook in `.claude/settings.json`, and write an
139
+ `.okforge.config.json` describing the target project's folder-to-source mapping.
140
+ The mapping is the only project-specific part — both the skill and the nudge read
141
+ it from there.
@@ -0,0 +1,124 @@
1
+ ---
2
+ name: okf
3
+ description: >-
4
+ Maintain the Open Knowledge Format (OKF) knowledge bundle under okf/. Use
5
+ whenever the user wants to update, refresh, or regenerate OKF docs, set up an
6
+ OKF bundle, check OKF conformance, or when source code that the bundle
7
+ documents (config schemas, web API routes, CLI commands, runtime subsystems,
8
+ example crews, ADRs) has changed and the docs need to catch up. Three modes:
9
+ scaffold (create the bundle), refresh (regenerate a folder's docs from current
10
+ source), and check (conformance and dead-link lint). Prefer this skill over
11
+ hand-editing okf/ so the format, the folder<->source mapping, and link
12
+ integrity stay consistent.
13
+ ---
14
+
15
+ # Open Knowledge Format (OKF) maintenance
16
+
17
+ OKF is an open, human- and agent-friendly format for knowledge — the metadata
18
+ and curated insight that surrounds a system. This repo's bundle lives at `okf/`.
19
+ Spec: https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md
20
+
21
+ The bundle is **derived** from source. Each folder is generated from specific
22
+ files; when those files change, the folder's docs drift. This skill keeps three
23
+ things consistent so you can focus on accurate prose: the OKF format, the
24
+ folder<->source mapping, and link integrity.
25
+
26
+ A bundled CLI owns the mechanics; you own the prose. Run it with `npx` from the
27
+ project root (Node >= 20.12):
28
+
29
+ ```bash
30
+ npx okforge <command> # map | folders | sources <folder> | stale | check | nudge
31
+ ```
32
+
33
+ ## Pick the mode from what the user asked
34
+
35
+ - **"refresh okf", "update the OKF docs for X", "the API changed, update okf"**
36
+ → Refresh mode (the common case).
37
+ - **"set up okf", "create an OKF bundle", bundle missing** → Scaffold mode.
38
+ - **"check okf", "is the bundle conformant", "any dead links"** → Check mode.
39
+
40
+ ## The folder <-> source mapping
41
+
42
+ The mapping is **per-repository data**, declared in `.okforge.config.json` at the
43
+ project root. okforge ships with none of it. The file shape is:
44
+
45
+ ```json
46
+ {
47
+ "folders": {
48
+ "runtime_concepts": ["packages/foo/src/model/", "packages/foo/src/event/"],
49
+ "config_formats": ["packages/foo/data/schemas/thing.schema.json"]
50
+ }
51
+ }
52
+ ```
53
+
54
+ Each key is an OKF concept folder; each value is the list of source path prefixes
55
+ that folder is derived from. `npx okforge map` prints the resolved mapping;
56
+ `npx okforge sources <folder>` prints one folder's source paths;
57
+ `npx okforge folders` lists the declared folders. Never hardcode the mapping in
58
+ docs — read it from the config so there is one source of truth (the hook reads it
59
+ too). When the codebase moves, edit `.okforge.config.json`.
60
+
61
+ ## Refresh mode
62
+
63
+ 1. Determine which folder(s) to refresh. If the user named one, use it. If they
64
+ said "whatever changed", run `npx okforge stale` — it lists folders whose
65
+ source changed since HEAD without the folder being edited.
66
+ 2. For each folder, run `npx okforge sources <folder>` and **READ those real
67
+ files**.
68
+ 3. Regenerate the affected concept docs from what you read, following the OKF
69
+ authoring rules below. Only rewrite docs whose underlying source actually
70
+ changed; leave correct docs untouched. Preserve existing filenames unless the
71
+ source they document was renamed or removed.
72
+ 4. If a concept's source was deleted, delete its doc and remove it from the
73
+ folder `index.md`. If a new source appeared, add a new concept doc and link
74
+ it from `index.md`.
75
+ 5. Update the folder `index.md`, and if folders were added/removed update the
76
+ root `okf/index.md`, the `.okforge.config.json` mapping, and prepend a dated
77
+ entry to `okf/log.md`.
78
+ 6. Run `npx okforge check` and resolve every problem it reports before finishing.
79
+
80
+ ## Scaffold mode
81
+
82
+ Create `.okforge.config.json` at the project root with the folder<->source
83
+ mapping for this repository (ask the user or infer it from the layout). Then
84
+ create `okf/index.md` (the only file with frontmatter: `okf_version: "0.1"` and
85
+ `type: Bundle Index`) and `okf/log.md`. Create the folders from the mapping and
86
+ refresh each. Finish with `npx okforge check`.
87
+
88
+ ## Check mode
89
+
90
+ Run `npx okforge check`. It verifies snake_case names, that every non-index `.md`
91
+ has a non-empty frontmatter `type`, that sub-folder `index.md` files carry no
92
+ frontmatter, and that bundle-relative `.md` links resolve. Report results; fix
93
+ problems if the user asked you to.
94
+
95
+ ## OKF authoring rules (follow exactly when writing docs)
96
+
97
+ - **File names**: snake_case only. No kebab-case, no spaces.
98
+ - **Concept docs**: every non-index `.md` starts with a YAML frontmatter block
99
+ delimited by `---` lines. Required: `type` (non-empty, e.g. `Config Format`,
100
+ `Concept`, `Data Model`, `API Endpoint`, `CLI Command`, `Crew`, `Package`).
101
+ Recommended: `title`, `description` (one sentence), `resource` (path/URI of
102
+ the real underlying asset), `tags`, `timestamp` (ISO 8601 — set to today's
103
+ date on refresh).
104
+ - **Body**: favor structural markdown — headings, lists, tables, fenced code —
105
+ over prose. Use conventional sections where they apply: `# Schema` (field/
106
+ shape), `# Examples` (code), `# Citations` (sources).
107
+ - **Index files** (reserved): `index.md` has NO frontmatter (except the root
108
+ bundle index). It lists the folder's concepts as bulleted markdown links with
109
+ one-line descriptions, optionally grouped under `#` headings.
110
+ - **Links**: cross-link concepts with bundle-relative absolute paths, e.g.
111
+ `[job store](/runtime_concepts/job_store.md)`. Link to real repo source files
112
+ (in `# Citations`) with repo-relative paths from the doc, e.g.
113
+ `../../packages/foo/src/model/job_store.ts`.
114
+ - **Grounding (critical)**: every claim must come from the real source you read.
115
+ Do not invent field names, routes, flags, states, or behavior. If uncertain,
116
+ omit. Quote real schema fields and real route paths.
117
+ - **Style**: plain English, no slang, no abbreviations.
118
+
119
+ ## Companion hook
120
+
121
+ A `Stop` hook (`npx okforge nudge`, registered in `.claude/settings.json`) nudges
122
+ at session end when mapped source changed but `okf/` was not updated. It reads the
123
+ same `.okforge.config.json` mapping via `npx okforge stale`, so editing the
124
+ mapping updates both the skill and the nudge.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jerome Etienne
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # okforge
2
+
3
+ Deterministic mechanics and a Stop-hook nudge for the **okf** Claude Code skill,
4
+ which maintains an [Open Knowledge Format](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)
5
+ (OKF) knowledge bundle under `okf/` in any repository.
6
+
7
+ The skill prose lives in [`.claude/skills/okf/`](.claude/skills/okf); its
8
+ deterministic mechanics live in [`src/`](src) as a small TypeScript CLI. The model
9
+ writes the prose; the CLI answers "what is each folder derived from?" and "is the
10
+ bundle still well-formed?".
11
+
12
+ ## Usable in any repository
13
+
14
+ okforge ships with **no** repository-specific paths. Each repo declares its own
15
+ folder-to-source mapping in `.okforge.config.json` at the project root:
16
+
17
+ ```json
18
+ {
19
+ "folders": {
20
+ "runtime_concepts": ["packages/foo/src/model/", "packages/foo/src/event/"],
21
+ "config_formats": ["packages/foo/data/schemas/thing.schema.json"]
22
+ }
23
+ }
24
+ ```
25
+
26
+ With no config present, `map`/`folders` are empty and `stale` is a no-op; `check`
27
+ still works, since it lints the bundle's markdown alone.
28
+
29
+ ## The `okforge` CLI
30
+
31
+ Run with `npx` (Node >= 20.12). `<dir>` defaults to the current directory.
32
+
33
+ | Command | Purpose |
34
+ |---|---|
35
+ | `okforge map [<dir>]` | Print the full folder-to-source mapping. |
36
+ | `okforge folders [<dir>]` | List the OKF concept folders. |
37
+ | `okforge sources <folder> [<dir>]` | Print the source paths a folder is derived from. |
38
+ | `okforge stale [<dir>]` | List folders whose source changed since HEAD while the folder was not edited. |
39
+ | `okforge check [<dir>]` | Conformance + dead-link lint; exits non-zero on problems. |
40
+ | `okforge nudge` | Stop-hook entry: read the hook payload on stdin and maybe remind. |
41
+
42
+ ## Development
43
+
44
+ ```bash
45
+ npm install
46
+ npm run okforge -- <command> # run the CLI from source via tsx
47
+ npm run typecheck # tsc --noEmit
48
+ npm run build # compile to dist/
49
+ ```
50
+
51
+ ## Layout
52
+
53
+ ```
54
+ src/
55
+ ├── cli.ts Commander entry; wires the subcommands below
56
+ ├── misc/
57
+ │ └── okf_store.ts mapping load, stale detection, conformance lint
58
+ └── commands/
59
+ ├── map_command.ts print the folder-to-source mapping
60
+ ├── folders_command.ts list the concept folders
61
+ ├── sources_command.ts print a folder's source paths
62
+ ├── stale_command.ts folders whose source changed since HEAD
63
+ ├── check_command.ts conformance + dead-link lint
64
+ └── nudge_command.ts the Stop-hook nudge
65
+ .claude/skills/okf/
66
+ ├── SKILL.md instructions Claude loads
67
+ └── README.md human-facing skill overview
68
+ ```
69
+
70
+ ## License
71
+
72
+ MIT © Jerome Etienne
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+ import Fs from 'node:fs';
3
+ import Path from 'node:path';
4
+ import { Command } from 'commander';
5
+ import Chalk from 'chalk';
6
+ import { MapCommand } from './commands/map_command.js';
7
+ import { FoldersCommand } from './commands/folders_command.js';
8
+ import { SourcesCommand } from './commands/sources_command.js';
9
+ import { StaleCommand } from './commands/stale_command.js';
10
+ import { CheckCommand } from './commands/check_command.js';
11
+ import { NudgeCommand } from './commands/nudge_command.js';
12
+ import { InstallCommand } from './commands/install_command.js';
13
+ /** Wire up the subcommands and run them. */
14
+ async function main() {
15
+ const packageJsonPath = Path.join(import.meta.dirname, '..', 'package.json');
16
+ const { version } = JSON.parse(Fs.readFileSync(packageJsonPath, 'utf8'));
17
+ const program = new Command();
18
+ program
19
+ .name('okforge')
20
+ .description('Deterministic mechanics and Stop-hook nudge for the okf (Open Knowledge Format) skill')
21
+ .version(version, '-V, --version', 'output the version number');
22
+ program
23
+ .command('folders')
24
+ .description('List the OKF concept folders declared in .okforge.config.json')
25
+ .argument('[dir]', 'Repository root', '.')
26
+ .action((dir) => {
27
+ for (const folder of FoldersCommand.folders(Path.resolve(dir))) {
28
+ console.log(folder);
29
+ }
30
+ });
31
+ program
32
+ .command('map')
33
+ .description('Print the full folder -> sources mapping')
34
+ .argument('[dir]', 'Repository root', '.')
35
+ .action((dir) => {
36
+ for (const line of MapCommand.map(Path.resolve(dir))) {
37
+ console.log(line);
38
+ }
39
+ });
40
+ program
41
+ .command('sources')
42
+ .description('Print the source paths a folder is derived from')
43
+ .argument('<folder>', 'OKF concept folder')
44
+ .argument('[dir]', 'Repository root', '.')
45
+ .action((folder, dir) => {
46
+ for (const source of SourcesCommand.sources(Path.resolve(dir), folder)) {
47
+ console.log(source);
48
+ }
49
+ });
50
+ program
51
+ .command('stale')
52
+ .description('List folders whose source changed since HEAD while the folder was not edited')
53
+ .argument('[dir]', 'Repository root', '.')
54
+ .action((dir) => {
55
+ for (const line of StaleCommand.stale(Path.resolve(dir))) {
56
+ console.log(line);
57
+ }
58
+ });
59
+ program
60
+ .command('check')
61
+ .description('Conformance + dead-link lint; exits non-zero on problems')
62
+ .argument('[dir]', 'Repository root', '.')
63
+ .action((dir) => {
64
+ const cwd = Path.resolve(dir);
65
+ let result;
66
+ try {
67
+ result = CheckCommand.check(cwd);
68
+ }
69
+ catch (error) {
70
+ const message = error instanceof Error ? error.message : String(error);
71
+ console.error(message);
72
+ process.exit(2);
73
+ }
74
+ for (const problem of result.problems) {
75
+ console.log(problem);
76
+ }
77
+ if (result.problems.length === 0) {
78
+ console.log(result.summary);
79
+ return;
80
+ }
81
+ console.error(result.summary);
82
+ process.exit(1);
83
+ });
84
+ program
85
+ .command('nudge')
86
+ .description('Stop-hook companion: read the hook payload on stdin and maybe remind')
87
+ .action(async () => {
88
+ await NudgeCommand.nudge();
89
+ });
90
+ program
91
+ .command('install')
92
+ .description('Copy the bundled okf skill into an AI agent folder (e.g. .claude)')
93
+ .argument('[agent_folder]', 'Destination agent folder', '.')
94
+ .action((agentFolder) => {
95
+ const result = InstallCommand.install(agentFolder);
96
+ for (const file of result.files) {
97
+ console.log(`${Chalk.green(file.action)} ${file.destination}`);
98
+ }
99
+ console.log(Chalk.bold(`\n${result.files.length} file(s) → ${result.destinationDir}`));
100
+ console.log('Next: register `npx okforge nudge` as a Stop hook in .claude/settings.json.');
101
+ });
102
+ await program.parseAsync(process.argv);
103
+ }
104
+ main().catch((error) => {
105
+ const message = error instanceof Error ? error.message : String(error);
106
+ console.error(Chalk.red(`error: ${message}`));
107
+ process.exit(1);
108
+ });
109
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /** Outcome of a conformance run: the problems found and a summary line. */
2
+ export type CheckResult = {
3
+ problems: string[];
4
+ summary: string;
5
+ };
6
+ /** `check` — conformance + dead-link lint of the `okf/` bundle. */
7
+ export declare class CheckCommand {
8
+ /**
9
+ * Lint the bundle under `cwd`. Returns the problems and a summary line:
10
+ * `OK: N concept docs conformant` when clean, `FAILED: N problem(s)` otherwise.
11
+ * Throws when there is no `okf/` bundle.
12
+ */
13
+ static check(cwd: string): CheckResult;
14
+ }
15
+ //# sourceMappingURL=check_command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check_command.d.ts","sourceRoot":"","sources":["../../src/commands/check_command.ts"],"names":[],"mappings":"AAEA,2EAA2E;AAC3E,MAAM,MAAM,WAAW,GAAG;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,mEAAmE;AACnE,qBAAa,YAAY;IACxB;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW;CAOtC"}
@@ -0,0 +1,17 @@
1
+ import { OkfStore } from '../misc/okf_store.js';
2
+ /** `check` — conformance + dead-link lint of the `okf/` bundle. */
3
+ export class CheckCommand {
4
+ /**
5
+ * Lint the bundle under `cwd`. Returns the problems and a summary line:
6
+ * `OK: N concept docs conformant` when clean, `FAILED: N problem(s)` otherwise.
7
+ * Throws when there is no `okf/` bundle.
8
+ */
9
+ static check(cwd) {
10
+ const problems = OkfStore.check(cwd);
11
+ if (problems.length === 0) {
12
+ return { problems, summary: `OK: ${OkfStore.conceptCount(cwd)} concept docs conformant` };
13
+ }
14
+ return { problems, summary: `FAILED: ${problems.length} problem(s)` };
15
+ }
16
+ }
17
+ //# sourceMappingURL=check_command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check_command.js","sourceRoot":"","sources":["../../src/commands/check_command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQhD,mEAAmE;AACnE,MAAM,OAAO,YAAY;IACxB;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,GAAW;QACvB,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,0BAA0B,EAAE,CAAC;QAC3F,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,QAAQ,CAAC,MAAM,aAAa,EAAE,CAAC;IACvE,CAAC;CACD"}
@@ -0,0 +1,6 @@
1
+ /** `folders` — list the OKF concept folders, one per line. */
2
+ export declare class FoldersCommand {
3
+ /** The OKF concept folder names declared in `cwd`'s config, in declared order. */
4
+ static folders(cwd: string): string[];
5
+ }
6
+ //# sourceMappingURL=folders_command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folders_command.d.ts","sourceRoot":"","sources":["../../src/commands/folders_command.ts"],"names":[],"mappings":"AAEA,8DAA8D;AAC9D,qBAAa,cAAc;IAC1B,kFAAkF;IAClF,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE;CAGrC"}
@@ -0,0 +1,9 @@
1
+ import { OkfStore } from '../misc/okf_store.js';
2
+ /** `folders` — list the OKF concept folders, one per line. */
3
+ export class FoldersCommand {
4
+ /** The OKF concept folder names declared in `cwd`'s config, in declared order. */
5
+ static folders(cwd) {
6
+ return OkfStore.folders(cwd);
7
+ }
8
+ }
9
+ //# sourceMappingURL=folders_command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folders_command.js","sourceRoot":"","sources":["../../src/commands/folders_command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,8DAA8D;AAC9D,MAAM,OAAO,cAAc;IAC1B,kFAAkF;IAClF,MAAM,CAAC,OAAO,CAAC,GAAW;QACzB,OAAO,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;CACD"}
@@ -0,0 +1,25 @@
1
+ /** Outcome of copying a single skill file into the destination folder. */
2
+ export type InstalledFile = {
3
+ name: string;
4
+ action: 'created' | 'updated';
5
+ destination: string;
6
+ };
7
+ /** Summary returned by {@link InstallCommand.install}. */
8
+ export type InstallResult = {
9
+ destinationDir: string;
10
+ files: InstalledFile[];
11
+ };
12
+ /** `install` — copy the bundled okf skill into an AI agent folder (e.g. `.claude`). */
13
+ export declare class InstallCommand {
14
+ /**
15
+ * Copy the bundled `skills/okf/` tree into `agentFolder` (the agent directory,
16
+ * e.g. `.claude`), preserving the `skills/okf/...` layout, to set the skill up
17
+ * in a target project. Machine-local settings are never copied.
18
+ * @param agentFolder Destination agent folder; the caller defaults it to `.`.
19
+ * @returns The destination directory and the per-file outcome.
20
+ */
21
+ static install(agentFolder: string): InstallResult;
22
+ /** Paths of every file under `dir`, relative to `dir`, recursively. */
23
+ static listFiles(dir: string): string[];
24
+ }
25
+ //# sourceMappingURL=install_command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install_command.d.ts","sourceRoot":"","sources":["../../src/commands/install_command.ts"],"names":[],"mappings":"AAGA,0EAA0E;AAC1E,MAAM,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,0DAA0D;AAC1D,MAAM,MAAM,aAAa,GAAG;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,aAAa,EAAE,CAAC;CACvB,CAAC;AAEF,uFAAuF;AACvF,qBAAa,cAAc;IAC1B;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa;IAkBlD,uEAAuE;IACvE,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE;CAavC"}
@@ -0,0 +1,45 @@
1
+ import Fs from 'node:fs';
2
+ import Path from 'node:path';
3
+ /** `install` — copy the bundled okf skill into an AI agent folder (e.g. `.claude`). */
4
+ export class InstallCommand {
5
+ /**
6
+ * Copy the bundled `skills/okf/` tree into `agentFolder` (the agent directory,
7
+ * e.g. `.claude`), preserving the `skills/okf/...` layout, to set the skill up
8
+ * in a target project. Machine-local settings are never copied.
9
+ * @param agentFolder Destination agent folder; the caller defaults it to `.`.
10
+ * @returns The destination directory and the per-file outcome.
11
+ */
12
+ static install(agentFolder) {
13
+ const skillsDir = Path.join(import.meta.dirname, '..', '..', '.claude', 'skills');
14
+ if (Fs.existsSync(skillsDir) === false) {
15
+ throw new Error(`bundled skill files not found at ${skillsDir}`);
16
+ }
17
+ const destinationDir = Path.resolve(agentFolder);
18
+ const files = [];
19
+ for (const relative of InstallCommand.listFiles(skillsDir)) {
20
+ const name = Path.join('skills', relative);
21
+ const destination = Path.join(destinationDir, name);
22
+ const exists = Fs.existsSync(destination);
23
+ Fs.mkdirSync(Path.dirname(destination), { recursive: true });
24
+ Fs.copyFileSync(Path.join(skillsDir, relative), destination);
25
+ files.push({ name, action: exists === true ? 'updated' : 'created', destination });
26
+ }
27
+ return { destinationDir, files };
28
+ }
29
+ /** Paths of every file under `dir`, relative to `dir`, recursively. */
30
+ static listFiles(dir) {
31
+ const result = [];
32
+ for (const entry of Fs.readdirSync(dir, { withFileTypes: true })) {
33
+ if (entry.isDirectory() === true) {
34
+ for (const nested of InstallCommand.listFiles(Path.join(dir, entry.name))) {
35
+ result.push(Path.join(entry.name, nested));
36
+ }
37
+ }
38
+ else {
39
+ result.push(entry.name);
40
+ }
41
+ }
42
+ return result;
43
+ }
44
+ }
45
+ //# sourceMappingURL=install_command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install_command.js","sourceRoot":"","sources":["../../src/commands/install_command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAe7B,uFAAuF;AACvF,MAAM,OAAO,cAAc;IAC1B;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,CAAC,WAAmB;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QAClF,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,KAAK,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,oCAAoC,SAAS,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACjD,MAAM,KAAK,GAAoB,EAAE,CAAC;QAClC,KAAK,MAAM,QAAQ,IAAI,cAAc,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC3C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;YACpD,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;YAC1C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7D,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAC;YAC7D,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;IAClC,CAAC;IAED,uEAAuE;IACvE,MAAM,CAAC,SAAS,CAAC,GAAW;QAC3B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YAClE,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC;gBAClC,KAAK,MAAM,MAAM,IAAI,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;oBAC3E,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;gBAC5C,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;QACF,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;CACD"}
@@ -0,0 +1,6 @@
1
+ /** `map` — print the full folder -> sources mapping. */
2
+ export declare class MapCommand {
3
+ /** The mapping as printable lines: `## <folder>` headers with ` - <source>` rows. */
4
+ static map(cwd: string): string[];
5
+ }
6
+ //# sourceMappingURL=map_command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map_command.d.ts","sourceRoot":"","sources":["../../src/commands/map_command.ts"],"names":[],"mappings":"AAEA,wDAAwD;AACxD,qBAAa,UAAU;IACtB,sFAAsF;IACtF,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE;CAUjC"}