Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ The package exports both the root module and focused subpath modules:
| `@tasknotes/model/validation` | Task and time-entry validation |
| `@tasknotes/model/operations` | Host-independent task mutation planning, including materialized occurrence plans |
| `@tasknotes/model/frontmatter` | Markdown task document parse/serialize helpers |
| `@tasknotes/model/mdbase` | Canonical mdbase v0.3 config/type generation and TaskNotes extension resolution |
| `@tasknotes/model/mdbase` | Canonical mdbase v0.3 config, contract, schema, and implementing-type generation |
| `@tasknotes/model/conformance` | tasknotes-spec conformance operation dispatcher |
| `@tasknotes/model/runtime` | Host-independent mdbase runtime provider and host contracts |

Expand Down Expand Up @@ -198,7 +198,10 @@ The package build emits ESM, CommonJS, and TypeScript declaration output under `
The conformance adapter reports its claimed TaskNotes profile and implements
the official `core-lite` operation surface. Its fixture run currently passes
4,974 cases with zero failures; the extended-profile fixture remains outside
that claim. The mdbase generator is covered by round-trip tests that resolve
its emitted field roles and vocabularies back into model configuration.
that claim. The mdbase generator emits the `tasknotes.task 0.2.0` contract,
its two JSON Schemas, and a type whose `implements` entry contains field
mappings and TaskNotes behavior. Round-trip tests resolve those resources back
into model configuration so filesystem-backed hosts can treat the type as a
configuration provider.

The Obsidian plugin uses this package through its service layer and keeps runtime-only behavior, such as Obsidian vault writes, metadata-cache link resolution, notices, and plugin-specific clock hooks, outside the model package.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
},
"scripts": {
"clean": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"",
"sync:mdbase-contract": "node scripts/sync-tasknotes-contract.mjs",
"build": "npm run clean && node scripts/build.mjs && tsc -p tsconfig.types.json",
"prepack": "npm run build",
"test": "npm run build && node --test test/**/*.test.mjs",
Expand Down
31 changes: 31 additions & 0 deletions scripts/sync-tasknotes-contract.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { mkdir, readFile, writeFile } from "node:fs/promises";
import path from "node:path";

const specRoot =
process.env.TASKNOTES_SPEC_ROOT ??
path.resolve(import.meta.dirname, "../../tasknotes-spec");
const generatedPath = path.resolve(
import.meta.dirname,
"../src/generated/tasknotes-data-contract.ts"
);

const [taskSchema, bindingSchema] = await Promise.all(
["tasknotes-task.schema.json", "tasknotes-task-binding.schema.json"].map(
async (name) =>
JSON.parse(
await readFile(path.join(specRoot, "schemas", name), "utf8")
)
)
);

const source = `// Generated by scripts/sync-tasknotes-contract.mjs from tasknotes-spec.
// Do not edit this file directly.

export const TASKNOTES_TASK_SCHEMA = ${JSON.stringify(taskSchema, null, "\t")} as const;

export const TASKNOTES_TASK_BINDING_SCHEMA = ${JSON.stringify(bindingSchema, null, "\t")} as const;
`;

await mkdir(path.dirname(generatedPath), { recursive: true });
await writeFile(generatedPath, source);
console.log(`Synced TaskNotes data-contract schemas from ${specRoot}`);
Loading