dotdog 0.5.1 → 0.7.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/dist/cli.js CHANGED
@@ -2895,6 +2895,21 @@ function parseBlocks(lines, start, end) {
2895
2895
  }
2896
2896
  }
2897
2897
  }
2898
+ if (lines[i].startsWith("```")) {
2899
+ let fenceEnd = i + 1;
2900
+ while (fenceEnd < end && !lines[fenceEnd].startsWith("```"))
2901
+ fenceEnd++;
2902
+ const blockEnd = fenceEnd < end ? fenceEnd + 1 : end;
2903
+ blocks.push({
2904
+ kind: "prose",
2905
+ content: lines.slice(i, blockEnd).join(`
2906
+ `).trim(),
2907
+ lineStart: i + 1,
2908
+ lineEnd: blockEnd
2909
+ });
2910
+ i = blockEnd;
2911
+ continue;
2912
+ }
2898
2913
  const proseStart = i;
2899
2914
  while (i < end && !isBlockStart(lines[i]) && !lines[i].startsWith("```")) {
2900
2915
  i++;
@@ -4660,6 +4675,59 @@ kitCmd.command("init <kit>").description("Init a project from a kit").option("-p
4660
4675
  Kit "${kit}" initialized in specs/${projectName}/`));
4661
4676
  console.log(source_default.gray(` Run: dotdog validate`));
4662
4677
  });
4678
+ program2.command("badge [dir]").description("Generate dotdog-badge.svg (shields.io style) showing savings").action((d = ".") => {
4679
+ const dir = resolvePath2(d);
4680
+ const dirs = [join3(dir, "projects"), join3(dir, "specs"), dir];
4681
+ let found = false;
4682
+ for (const dd of dirs) {
4683
+ if (!existsSync3(dd))
4684
+ continue;
4685
+ const projects = readdirSync3(dd, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
4686
+ for (const p of projects) {
4687
+ const pd = join3(dd, p);
4688
+ const dagFile = join3(pd, `${p}.dag`);
4689
+ if (!existsSync3(join3(pd, "SPEC.dog")))
4690
+ continue;
4691
+ if (!existsSync3(dagFile)) {
4692
+ console.log(source_default.red(` No .dag for ${p}. Run dotdog compile first.`));
4693
+ continue;
4694
+ }
4695
+ const dag = JSON.parse(readFileSync3(dagFile, "utf-8"));
4696
+ const savings = dag.tk && dag.tk.sv ? Math.round(dag.tk.sv) : 0;
4697
+ const label = "spec savings";
4698
+ const value = `${savings}%`;
4699
+ const color = savings > 90 ? "#4c1" : savings > 70 ? "#dfb317" : "#e05d44";
4700
+ const labelLen = Math.round(label.length * 7.2);
4701
+ const valueLen = Math.round(value.length * 7.2);
4702
+ const leftW = Math.max(labelLen + 10, 70);
4703
+ const rightW = Math.max(valueLen + 10, 40);
4704
+ const totalW = leftW + rightW;
4705
+ const leftX = leftW / 2 * 10;
4706
+ const rightX = (leftW + rightW / 2) * 10;
4707
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${totalW}" height="20" role="img" aria-label="${label}: ${value}">
4708
+ <title>${label}: ${value}</title>
4709
+ <linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient>
4710
+ <clipPath id="r"><rect width="${totalW}" height="20" rx="3" fill="#fff"/></clipPath>
4711
+ <g clip-path="url(#r)">
4712
+ <rect width="${leftW}" height="20" fill="#555"/>
4713
+ <rect x="${leftW}" width="${rightW}" height="20" fill="${color}"/>
4714
+ <rect width="${totalW}" height="20" fill="url(#s)"/>
4715
+ </g>
4716
+ <g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
4717
+ <g transform="scale(.1)">
4718
+ <text x="${leftX}" y="140" textLength="${labelLen * 10}">${label}</text>
4719
+ <text x="${rightX}" y="140" textLength="${valueLen * 10}">${value}</text>
4720
+ </g>
4721
+ </g>
4722
+ </svg>`;
4723
+ writeFileSync2(join3(dir, "dotdog-badge.svg"), svg);
4724
+ console.log(source_default.green(` ✓ dotdog-badge.svg (${label}: ${value})`));
4725
+ found = true;
4726
+ }
4727
+ }
4728
+ if (!found)
4729
+ console.log(source_default.yellow("No projects found. Run dotdog init first."));
4730
+ });
4663
4731
  program2.parse();
4664
4732
  export {
4665
4733
  parseToJSON,
@@ -0,0 +1,39 @@
1
+ # DAO Governance
2
+
3
+ > Community governance starter. Members create proposals, vote, and execute approved treasury actions.
4
+
5
+ ## Product
6
+
7
+ A DAO governance workspace. Members join with voting power, submit proposals, cast votes, and execute passed proposals against a shared treasury.
8
+
9
+ ## What the User Sees
10
+
11
+ ### Screen: Proposal List
12
+
13
+ +------------------------------------------+
14
+ | DAO Proposals [New] |
15
+ |------------------------------------------|
16
+ | Upgrade Grants Program Active |
17
+ | Fund Security Audit Passed |
18
+ | Sponsor Builder Event Draft |
19
+ +------------------------------------------+
20
+
21
+ ### Screen: Proposal Detail
22
+
23
+ +------------------------------------------+
24
+ | Upgrade Grants Program |
25
+ |------------------------------------------|
26
+ | Status: Active |
27
+ | For: 62% Against: 18% Abstain: 20% |
28
+ | |
29
+ | [Vote For] [Vote Against] [Abstain] |
30
+ +------------------------------------------+
31
+
32
+ ## User Stories
33
+
34
+ | ID | Story | Pri | Acceptance |
35
+ |----|-------|-----|------------|
36
+ | US-01 | Member creates a proposal | P0 | Proposal appears as draft |
37
+ | US-02 | Member casts a vote | P0 | Vote is counted once |
38
+ | US-03 | Proposal reaches quorum | P0 | Status becomes passed or rejected |
39
+ | US-04 | Approved proposal executes | P1 | Treasury allocation is recorded |
@@ -0,0 +1,9 @@
1
+ # DAO Governance Constitution
2
+
3
+ ## Core Rules
4
+
5
+ 1. One member can cast one vote per proposal.
6
+ 2. Proposal execution requires both quorum and majority approval.
7
+ 3. Treasury allocations must reference an approved proposal.
8
+ 4. Proposal state changes are append-only and auditable.
9
+ 5. Voting power is read at the proposal snapshot block.
@@ -0,0 +1,134 @@
1
+ # DAO Governance Data Model
2
+
3
+ ## Entities
4
+
5
+ ### Entity: Member
6
+
7
+ A DAO participant with voting power.
8
+
9
+ ```yaml
10
+ entity: Member
11
+ type: entity
12
+ properties:
13
+ id:
14
+ type: string
15
+ required: true
16
+ wallet:
17
+ type: string
18
+ required: true
19
+ voting_power:
20
+ type: number
21
+ required: true
22
+ states: [active, delegated, suspended]
23
+ lifecycle: active → delegated → suspended
24
+ ```
25
+
26
+ ### Entity: Proposal
27
+
28
+ A governance item submitted for member voting.
29
+
30
+ ```yaml
31
+ entity: Proposal
32
+ type: entity
33
+ properties:
34
+ id:
35
+ type: string
36
+ required: true
37
+ title:
38
+ type: string
39
+ required: true
40
+ quorum_required:
41
+ type: number
42
+ required: true
43
+ status:
44
+ type: enum
45
+ required: true
46
+ states: [draft, active, passed, rejected, executed]
47
+ lifecycle: draft → active → passed → executed
48
+ ```
49
+
50
+ ### Entity: Vote
51
+
52
+ A member decision on a proposal.
53
+
54
+ ```yaml
55
+ entity: Vote
56
+ type: event
57
+ properties:
58
+ member_id:
59
+ type: string
60
+ required: true
61
+ proposal_id:
62
+ type: string
63
+ required: true
64
+ choice:
65
+ type: enum
66
+ required: true
67
+ weight:
68
+ type: number
69
+ required: true
70
+ states: [cast, counted]
71
+ lifecycle: cast → counted
72
+ ```
73
+
74
+ ### Entity: TreasuryAllocation
75
+
76
+ Funds allocated by an executed proposal.
77
+
78
+ ```yaml
79
+ entity: TreasuryAllocation
80
+ type: entity
81
+ properties:
82
+ id:
83
+ type: string
84
+ required: true
85
+ proposal_id:
86
+ type: string
87
+ required: true
88
+ amount:
89
+ type: number
90
+ required: true
91
+ recipient:
92
+ type: string
93
+ required: true
94
+ states: [approved, executed, canceled]
95
+ lifecycle: approved → executed
96
+ ```
97
+
98
+ ## Relationships
99
+
100
+ ### Relationship: Member → Proposal
101
+
102
+ ```yaml
103
+ relationship: Member → Proposal
104
+ verb: submits
105
+ cardinality: 1:N
106
+ required: true
107
+ ```
108
+
109
+ ### Relationship: Member → Vote
110
+
111
+ ```yaml
112
+ relationship: Member → Vote
113
+ verb: casts
114
+ cardinality: 1:N
115
+ required: true
116
+ ```
117
+
118
+ ### Relationship: Proposal → Vote
119
+
120
+ ```yaml
121
+ relationship: Proposal → Vote
122
+ verb: receives
123
+ cardinality: 1:N
124
+ required: true
125
+ ```
126
+
127
+ ### Relationship: Proposal → TreasuryAllocation
128
+
129
+ ```yaml
130
+ relationship: Proposal → TreasuryAllocation
131
+ verb: authorizes
132
+ cardinality: 1:1
133
+ required: false
134
+ ```
@@ -0,0 +1,8 @@
1
+ # SaaS Platform Constitution
2
+
3
+ ## Core Rules
4
+
5
+ 1. Organizations own their workspace data.
6
+ 2. Users access data only through organization membership.
7
+ 3. Plan limits must be enforced before billable usage is accepted.
8
+ 4. Subscription state controls access to paid features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dotdog",
3
- "version": "0.5.1",
3
+ "version": "0.7.0",
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",
@@ -47,5 +47,8 @@
47
47
  "homepage": "https://specdog.github.io/dotdog",
48
48
  "bugs": {
49
49
  "url": "https://github.com/specdog/dotdog/issues"
50
+ },
51
+ "scripts": {
52
+ "lint": "bun run --check src/"
50
53
  }
51
54
  }