dotdog 0.8.2 → 0.8.4

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 (2) hide show
  1. package/dist/cli.js +100 -9
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
3
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
2
4
 
3
5
  // ../../node_modules/.bun/commander@15.0.0/node_modules/commander/lib/error.js
4
6
  class CommanderError extends Error {
@@ -2854,6 +2856,26 @@ function parseBlocks(lines, start, end, errors2) {
2854
2856
  i = yamlEnd + 1;
2855
2857
  continue;
2856
2858
  }
2859
+ if (Array.isArray(yaml.relationships)) {
2860
+ for (const item of yaml.relationships) {
2861
+ blocks.push({
2862
+ kind: "relationship",
2863
+ source: item.from || item.source || "",
2864
+ target: item.to || item.target || "",
2865
+ verb: item.verb || "connects",
2866
+ description: item.description || "",
2867
+ cardinality: item.cardinality || "N:M",
2868
+ required: item.required === true,
2869
+ cascade: item.cascade || "none",
2870
+ invariants: [],
2871
+ yaml: item,
2872
+ lineStart: i + 1,
2873
+ lineEnd: yamlEnd
2874
+ });
2875
+ }
2876
+ i = yamlEnd + 1;
2877
+ continue;
2878
+ }
2857
2879
  if (yaml.event) {
2858
2880
  blocks.push({
2859
2881
  kind: "event",
@@ -2896,7 +2918,7 @@ function parseBlocks(lines, start, end, errors2) {
2896
2918
  i = yamlEnd + 1;
2897
2919
  continue;
2898
2920
  }
2899
- const key = yaml.prediction ? "prediction" : yaml.entity ? "entity" : yaml.event ? "event" : yaml.relationship || yaml.verb ? "relationship" : null;
2921
+ const key = yaml.prediction ? "prediction" : yaml.entity ? "entity" : yaml.event ? "event" : yaml.relationship || yaml.verb ? "relationship" : Array.isArray(yaml.relationships) ? "relationship_list" : null;
2900
2922
  if (key) {
2901
2923
  if (key === "prediction") {
2902
2924
  blocks.push({ kind: "prediction", statement: yaml.prediction || "", description: yaml.description || "", trigger: yaml.trigger || "", timeframe: yaml.timeframe || "", confidence: yaml.confidence || 0, measurement: yaml.measurement || "", status: yaml.status || "pending", yaml, lineStart: i + 1, lineEnd: yamlEnd });
@@ -2906,6 +2928,10 @@ function parseBlocks(lines, start, end, errors2) {
2906
2928
  blocks.push({ kind: "event", name: yaml.event || "", trigger: yaml.trigger || "", payload: {}, preconditions: [], postconditions: [], sideEffects: [], probability: null, yaml, lineStart: i + 1, lineEnd: yamlEnd });
2907
2929
  } else if (key === "relationship") {
2908
2930
  blocks.push({ kind: "relationship", source: yaml.source || "", target: yaml.target || "", verb: yaml.verb || "connects", description: yaml.description || "", cardinality: yaml.cardinality || "N:M", required: false, cascade: "none", invariants: [], yaml, lineStart: i + 1, lineEnd: yamlEnd });
2931
+ } else if (key === "relationship_list") {
2932
+ for (const item of yaml.relationships) {
2933
+ blocks.push({ kind: "relationship", source: item.from || item.source || "", target: item.to || item.target || "", verb: item.verb || "connects", description: item.description || "", cardinality: item.cardinality || "N:M", required: item.required === true, cascade: item.cascade || "none", invariants: [], yaml: item, lineStart: i + 1, lineEnd: yamlEnd });
2934
+ }
2909
2935
  }
2910
2936
  i = yamlEnd + 1;
2911
2937
  continue;
@@ -3021,13 +3047,19 @@ function buildEntityNode(name, description, yaml, lineStart, lineEnd) {
3021
3047
  const rawProps = yaml.properties;
3022
3048
  if (rawProps) {
3023
3049
  for (const [key, val] of Object.entries(rawProps)) {
3024
- if (typeof val === "object" && val !== null) {
3050
+ let resolved = val;
3051
+ if (typeof val === "string" && val.startsWith("{") && val.endsWith("}")) {
3052
+ const inline = parseInlineObject(val);
3053
+ if (inline)
3054
+ resolved = inline;
3055
+ }
3056
+ if (typeof resolved === "object" && resolved !== null) {
3025
3057
  properties[key] = {
3026
- type: val.type || "string",
3027
- required: val.required !== false,
3028
- default: val.default,
3029
- constraints: val.constraints,
3030
- example: val.example
3058
+ type: resolved.type || "string",
3059
+ required: resolved.required !== false,
3060
+ default: resolved.default,
3061
+ constraints: resolved.constraints,
3062
+ example: resolved.example
3031
3063
  };
3032
3064
  }
3033
3065
  }
@@ -3134,7 +3166,12 @@ function parseSimpleYAML(lines) {
3134
3166
  const topMatch = line.match(/^(\w[\w_]*):\s*(.+)?$/);
3135
3167
  if (topMatch && !line.startsWith(" ") && !line.startsWith("\t")) {
3136
3168
  if (inNested && currentKey) {
3137
- result[currentKey] = currentObj;
3169
+ if (Array.isArray(currentObj.__list) && currentObj.__list.length > 0) {
3170
+ result[currentKey] = currentObj.__list;
3171
+ delete currentObj.__list;
3172
+ } else {
3173
+ result[currentKey] = currentObj;
3174
+ }
3138
3175
  inNested = false;
3139
3176
  currentObj = {};
3140
3177
  }
@@ -3177,6 +3214,26 @@ function parseSimpleYAML(lines) {
3177
3214
  }
3178
3215
  continue;
3179
3216
  }
3217
+ const listMatch = line.match(/^\s{2}-(?:\s+)?(.+)?$/);
3218
+ if (listMatch && inNested && currentKey) {
3219
+ const item = (listMatch[1] || "").trim();
3220
+ if (!Array.isArray(currentObj.__list)) {
3221
+ currentObj.__list = [];
3222
+ }
3223
+ if (item.startsWith("{") && item.endsWith("}")) {
3224
+ const inline = parseInlineObject(item);
3225
+ currentObj.__list.push(inline || item);
3226
+ } else if (item === "true") {
3227
+ currentObj.__list.push(true);
3228
+ } else if (item === "false") {
3229
+ currentObj.__list.push(false);
3230
+ } else if (/^-?\d+(\.\d+)?$/.test(item)) {
3231
+ currentObj.__list.push(parseFloat(item));
3232
+ } else {
3233
+ currentObj.__list.push(item);
3234
+ }
3235
+ continue;
3236
+ }
3180
3237
  if (nestedMatch && !inNested) {
3181
3238
  const key = nestedMatch[1];
3182
3239
  const value = (nestedMatch[2] || "").trim();
@@ -3202,7 +3259,12 @@ function parseSimpleYAML(lines) {
3202
3259
  }
3203
3260
  }
3204
3261
  if (inNested && currentKey) {
3205
- result[currentKey] = currentObj;
3262
+ if (Array.isArray(currentObj.__list) && currentObj.__list.length > 0) {
3263
+ result[currentKey] = currentObj.__list;
3264
+ delete currentObj.__list;
3265
+ } else {
3266
+ result[currentKey] = currentObj;
3267
+ }
3206
3268
  }
3207
3269
  return result;
3208
3270
  }
@@ -4804,6 +4866,35 @@ program2.command("badge [dir]").description("Generate dotdog-badge.svg (shields.
4804
4866
  if (!found)
4805
4867
  console.log(source_default.yellow("No projects found. Run dotdog init first."));
4806
4868
  });
4869
+ program2.command("convert <file>").description("Convert an .md file to .dog — rename + validate").action((f) => {
4870
+ const { existsSync: existsSync4, renameSync, readFileSync: readFileSync4, writeFileSync: writeFileSync3 } = __require("fs");
4871
+ const { join: join4, dirname, basename } = __require("path");
4872
+ const path2 = resolvePath2(f);
4873
+ if (!existsSync4(path2)) {
4874
+ console.log(source_default.red(`File not found: ${f}`));
4875
+ return;
4876
+ }
4877
+ if (!path2.endsWith(".md")) {
4878
+ console.log(source_default.yellow(`Only .md files can be converted.`));
4879
+ return;
4880
+ }
4881
+ const dogPath = path2.replace(/\.md$/, ".dog");
4882
+ if (existsSync4(dogPath)) {
4883
+ console.log(source_default.yellow(`${dogPath} already exists.`));
4884
+ return;
4885
+ }
4886
+ const content = readFileSync4(path2, "utf-8");
4887
+ renameSync(path2, dogPath);
4888
+ if (!content.match(/^##\s/m)) {
4889
+ const stub = `## Product
4890
+
4891
+ (Describe your product here)
4892
+ `;
4893
+ writeFileSync3(dogPath, stub + content);
4894
+ }
4895
+ console.log(source_default.green(` ✓ ${basename(path2)} → ${basename(dogPath)}`));
4896
+ console.log(source_default.gray(" Run: dotdog validate"));
4897
+ });
4807
4898
  program2.parse();
4808
4899
  export {
4809
4900
  parseToJSON,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dotdog",
3
- "version": "0.8.2",
3
+ "version": "0.8.4",
4
4
  "description": "CLI tool for structured software specifications. Validate .dog files, compile .dag graphs, query via MCP.",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",