musubix3 0.1.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.
Files changed (97) hide show
  1. package/.github/plugin/marketplace.json +16 -0
  2. package/.github/skills/sdd-change/SKILL.md +78 -0
  3. package/.github/skills/sdd-design/SKILL.md +26 -0
  4. package/.github/skills/sdd-formal-codegraph/SKILL.md +53 -0
  5. package/.github/skills/sdd-implementation/SKILL.md +54 -0
  6. package/.github/skills/sdd-knowledge/SKILL.md +24 -0
  7. package/.github/skills/sdd-quality/SKILL.md +69 -0
  8. package/.github/skills/sdd-requirements/SKILL.md +42 -0
  9. package/.github/skills/sdd-traceability/SKILL.md +28 -0
  10. package/CHANGELOG.md +152 -0
  11. package/LICENSE +21 -0
  12. package/README-ja.md +573 -0
  13. package/README.md +639 -0
  14. package/assets/ADR-0001.md +15 -0
  15. package/assets/constitution.md +17 -0
  16. package/assets/design.md +13 -0
  17. package/assets/requirements.md +15 -0
  18. package/dist/packages/analysis/src/adapters.d.ts +12 -0
  19. package/dist/packages/analysis/src/adapters.js +167 -0
  20. package/dist/packages/analysis/src/adapters.js.map +1 -0
  21. package/dist/packages/analysis/src/attestation.d.ts +50 -0
  22. package/dist/packages/analysis/src/attestation.js +474 -0
  23. package/dist/packages/analysis/src/attestation.js.map +1 -0
  24. package/dist/packages/analysis/src/change.d.ts +53 -0
  25. package/dist/packages/analysis/src/change.js +337 -0
  26. package/dist/packages/analysis/src/change.js.map +1 -0
  27. package/dist/packages/analysis/src/config.d.ts +104 -0
  28. package/dist/packages/analysis/src/config.js +456 -0
  29. package/dist/packages/analysis/src/config.js.map +1 -0
  30. package/dist/packages/analysis/src/files.d.ts +13 -0
  31. package/dist/packages/analysis/src/files.js +103 -0
  32. package/dist/packages/analysis/src/files.js.map +1 -0
  33. package/dist/packages/analysis/src/formal.d.ts +82 -0
  34. package/dist/packages/analysis/src/formal.js +579 -0
  35. package/dist/packages/analysis/src/formal.js.map +1 -0
  36. package/dist/packages/analysis/src/gate.d.ts +56 -0
  37. package/dist/packages/analysis/src/gate.js +484 -0
  38. package/dist/packages/analysis/src/gate.js.map +1 -0
  39. package/dist/packages/analysis/src/graph.d.ts +52 -0
  40. package/dist/packages/analysis/src/graph.js +737 -0
  41. package/dist/packages/analysis/src/graph.js.map +1 -0
  42. package/dist/packages/analysis/src/index.d.ts +17 -0
  43. package/dist/packages/analysis/src/index.js +18 -0
  44. package/dist/packages/analysis/src/index.js.map +1 -0
  45. package/dist/packages/analysis/src/knowledge.d.ts +29 -0
  46. package/dist/packages/analysis/src/knowledge.js +95 -0
  47. package/dist/packages/analysis/src/knowledge.js.map +1 -0
  48. package/dist/packages/analysis/src/model-correspondence.d.ts +45 -0
  49. package/dist/packages/analysis/src/model-correspondence.js +310 -0
  50. package/dist/packages/analysis/src/model-correspondence.js.map +1 -0
  51. package/dist/packages/analysis/src/mutation.d.ts +54 -0
  52. package/dist/packages/analysis/src/mutation.js +299 -0
  53. package/dist/packages/analysis/src/mutation.js.map +1 -0
  54. package/dist/packages/analysis/src/order.d.ts +23 -0
  55. package/dist/packages/analysis/src/order.js +89 -0
  56. package/dist/packages/analysis/src/order.js.map +1 -0
  57. package/dist/packages/analysis/src/performance.d.ts +65 -0
  58. package/dist/packages/analysis/src/performance.js +319 -0
  59. package/dist/packages/analysis/src/performance.js.map +1 -0
  60. package/dist/packages/analysis/src/process.d.ts +14 -0
  61. package/dist/packages/analysis/src/process.js +79 -0
  62. package/dist/packages/analysis/src/process.js.map +1 -0
  63. package/dist/packages/analysis/src/tdd.d.ts +65 -0
  64. package/dist/packages/analysis/src/tdd.js +353 -0
  65. package/dist/packages/analysis/src/tdd.js.map +1 -0
  66. package/dist/packages/analysis/src/trace.d.ts +45 -0
  67. package/dist/packages/analysis/src/trace.js +242 -0
  68. package/dist/packages/analysis/src/trace.js.map +1 -0
  69. package/dist/packages/analysis/src/workflow.d.ts +59 -0
  70. package/dist/packages/analysis/src/workflow.js +405 -0
  71. package/dist/packages/analysis/src/workflow.js.map +1 -0
  72. package/dist/packages/cli/src/install.d.ts +15 -0
  73. package/dist/packages/cli/src/install.js +71 -0
  74. package/dist/packages/cli/src/install.js.map +1 -0
  75. package/dist/packages/cli/src/main.d.ts +3 -0
  76. package/dist/packages/cli/src/main.js +364 -0
  77. package/dist/packages/cli/src/main.js.map +1 -0
  78. package/dist/packages/domain/src/constitution.d.ts +3 -0
  79. package/dist/packages/domain/src/constitution.js +46 -0
  80. package/dist/packages/domain/src/constitution.js.map +1 -0
  81. package/dist/packages/domain/src/design.d.ts +8 -0
  82. package/dist/packages/domain/src/design.js +59 -0
  83. package/dist/packages/domain/src/design.js.map +1 -0
  84. package/dist/packages/domain/src/index.d.ts +5 -0
  85. package/dist/packages/domain/src/index.js +6 -0
  86. package/dist/packages/domain/src/index.js.map +1 -0
  87. package/dist/packages/domain/src/markdown.d.ts +16 -0
  88. package/dist/packages/domain/src/markdown.js +72 -0
  89. package/dist/packages/domain/src/markdown.js.map +1 -0
  90. package/dist/packages/domain/src/requirements.d.ts +3 -0
  91. package/dist/packages/domain/src/requirements.js +195 -0
  92. package/dist/packages/domain/src/requirements.js.map +1 -0
  93. package/dist/packages/domain/src/types.d.ts +100 -0
  94. package/dist/packages/domain/src/types.js +14 -0
  95. package/dist/packages/domain/src/types.js.map +1 -0
  96. package/package.json +59 -0
  97. package/plugin.json +9 -0
@@ -0,0 +1,72 @@
1
+ import { parseDocument } from 'yaml';
2
+ import { error } from './types.js';
3
+ export function markdown(text, path = '<input>') {
4
+ const lines = text.replace(/^\uFEFF/, '').replace(/\r\n/g, '\n').split('\n');
5
+ const diagnostics = [];
6
+ let metadata = {};
7
+ let start = 0;
8
+ if (lines[0]?.trim() === '---') {
9
+ const end = lines.findIndex((line, i) => i > 0 && line.trim() === '---');
10
+ if (end === -1) {
11
+ diagnostics.push(error('MARKDOWN_FRONTMATTER', 'Unterminated YAML frontmatter.', path, 1));
12
+ start = lines.length;
13
+ }
14
+ else {
15
+ const doc = parseDocument(lines.slice(1, end).join('\n'), { uniqueKeys: true });
16
+ if (doc.errors.length) {
17
+ diagnostics.push(error('MARKDOWN_FRONTMATTER', doc.errors.map((e) => e.message).join('; '), path, 1));
18
+ }
19
+ else {
20
+ const value = doc.toJSON();
21
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
22
+ metadata = value;
23
+ }
24
+ else {
25
+ diagnostics.push(error('MARKDOWN_FRONTMATTER', 'Frontmatter must be a mapping.', path, 1));
26
+ }
27
+ }
28
+ start = end + 1;
29
+ }
30
+ }
31
+ const sections = [];
32
+ let current;
33
+ let fence;
34
+ for (let i = start; i < lines.length; i++) {
35
+ const line = lines[i] ?? '';
36
+ const delimiter = /^\s*(`{3,}|~{3,})/.exec(line)?.[1];
37
+ if (delimiter) {
38
+ if (!fence)
39
+ fence = delimiter;
40
+ else if (delimiter[0] === fence[0] && delimiter.length >= fence.length)
41
+ fence = undefined;
42
+ continue;
43
+ }
44
+ if (fence)
45
+ continue;
46
+ const heading = /^(#{2,6})\s+([A-Za-z]+-[^\s::]+)(?:\s*[::-]\s*|\s+)?(.*)$/.exec(line);
47
+ if (heading) {
48
+ current = { id: heading[2] ?? '', title: heading[3]?.trim() ?? '', body: '', line: i + 1, level: heading[1]?.length ?? 2 };
49
+ sections.push(current);
50
+ }
51
+ else if (current) {
52
+ current.body += `${line}\n`;
53
+ }
54
+ }
55
+ return { metadata, sections, diagnostics };
56
+ }
57
+ export function field(body, names) {
58
+ return new RegExp(`^\\s*(?:[-*]\\s+)?(?:\\*\\*)?(?:${names})(?:\\*\\*)?\\s*[::]\\s*(.+)$`, 'im').exec(body)?.[1]?.trim() ?? '';
59
+ }
60
+ export function references(text, prefix) {
61
+ return [...new Set(text.match(new RegExp(`\\b${prefix}-[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*\\b`, 'g')) ?? [])];
62
+ }
63
+ export function duplicates(sections, path) {
64
+ const seen = new Set();
65
+ return sections.flatMap((section) => {
66
+ if (seen.has(section.id))
67
+ return [error('DUPLICATE_ID', `Duplicate ID ${section.id}.`, path, section.line)];
68
+ seen.add(section.id);
69
+ return [];
70
+ });
71
+ }
72
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../../../packages/domain/src/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type EarsPattern, type Requirement, type Validation } from './types.js';
2
+ export declare function classifyEars(statement: string): EarsPattern | null;
3
+ export declare function validateRequirements(text: string, path?: string): Validation<Requirement[]>;
@@ -0,0 +1,195 @@
1
+ import { duplicates, field, markdown } from './markdown.js';
2
+ import { error, ids, validation, } from './types.js';
3
+ function explicitObject(text, fieldName, path, line, diagnostics) {
4
+ if (!text)
5
+ return null;
6
+ try {
7
+ const value = JSON.parse(text);
8
+ if (!value || typeof value !== 'object' || Array.isArray(value))
9
+ throw new Error('must be a JSON object');
10
+ return value;
11
+ }
12
+ catch (cause) {
13
+ diagnostics.push(error(`REQ_${fieldName.toUpperCase()}_SCHEMA`, `${fieldName} must be strict single-line JSON: ${cause instanceof Error ? cause.message : String(cause)}.`, path, line));
14
+ return null;
15
+ }
16
+ }
17
+ function exactKeys(value, allowed) {
18
+ return Object.keys(value).every((key) => allowed.includes(key));
19
+ }
20
+ function atom(value) {
21
+ return typeof value === 'string' && /^[\p{L}_][\p{L}\p{N}_.:-]{0,127}$/u.test(value);
22
+ }
23
+ function parseFormal(text, path, line, diagnostics) {
24
+ const value = explicitObject(text, 'formal', path, line, diagnostics);
25
+ if (!value)
26
+ return null;
27
+ let constraint = null;
28
+ if (value.kind === 'conditional'
29
+ && exactKeys(value, ['kind', 'condition', 'consequence', 'conditionValue', 'consequenceValue'])
30
+ && atom(value.condition) && atom(value.consequence)
31
+ && (value.conditionValue === undefined || typeof value.conditionValue === 'boolean')
32
+ && (value.consequenceValue === undefined || typeof value.consequenceValue === 'boolean')) {
33
+ constraint = {
34
+ kind: 'conditional',
35
+ condition: value.condition,
36
+ consequence: value.consequence,
37
+ conditionValue: value.conditionValue !== false,
38
+ consequenceValue: value.consequenceValue !== false,
39
+ };
40
+ }
41
+ else if (value.kind === 'numeric'
42
+ && exactKeys(value, ['kind', 'metric', 'operator', 'value', 'unit'])
43
+ && atom(value.metric) && ['<', '<=', '=', '>=', '>'].includes(String(value.operator))
44
+ && typeof value.value === 'number' && Number.isSafeInteger(value.value)
45
+ && (value.unit === undefined || atom(value.unit))) {
46
+ constraint = {
47
+ kind: 'numeric',
48
+ metric: value.metric,
49
+ operator: value.operator,
50
+ value: value.value,
51
+ ...(typeof value.unit === 'string' ? { unit: value.unit } : {}),
52
+ };
53
+ }
54
+ else if (value.kind === 'temporal'
55
+ && exactKeys(value, ['kind', 'trigger', 'response', 'withinMs', 'afterMs'])
56
+ && atom(value.trigger) && atom(value.response)
57
+ && (value.afterMs === undefined
58
+ || (typeof value.afterMs === 'number' && Number.isSafeInteger(value.afterMs) && value.afterMs >= 0))
59
+ && typeof value.withinMs === 'number' && Number.isSafeInteger(value.withinMs) && value.withinMs > 0) {
60
+ constraint = {
61
+ kind: 'temporal',
62
+ trigger: value.trigger,
63
+ response: value.response,
64
+ withinMs: value.withinMs,
65
+ ...(typeof value.afterMs === 'number' ? { afterMs: value.afterMs } : {}),
66
+ };
67
+ }
68
+ else if (value.kind === 'transition'
69
+ && exactKeys(value, ['kind', 'from', 'event', 'to'])
70
+ && atom(value.from) && atom(value.event) && atom(value.to)) {
71
+ constraint = { kind: 'transition', from: value.from, event: value.event, to: value.to };
72
+ }
73
+ if (!constraint)
74
+ diagnostics.push(error('REQ_FORMAL_SCHEMA', 'Formal must match the conditional, numeric, temporal, or transition constraint schema.', path, line));
75
+ return constraint;
76
+ }
77
+ function parsePerformance(text, path, line, diagnostics) {
78
+ const value = explicitObject(text, 'performance', path, line, diagnostics);
79
+ if (!value)
80
+ return null;
81
+ if (!exactKeys(value, ['counter', 'max', 'testId', 'unit'])
82
+ || !atom(value.counter)
83
+ || typeof value.max !== 'number' || !Number.isSafeInteger(value.max) || value.max < 0
84
+ || typeof value.testId !== 'string' || !ids.test.test(value.testId)
85
+ || (value.unit !== undefined && value.unit !== 'operations')) {
86
+ diagnostics.push(error('REQ_PERFORMANCE_SCHEMA', 'Performance must contain counter, nonnegative integer max, TEST-* testId, and optional unit \"operations\".', path, line));
87
+ return null;
88
+ }
89
+ return { counter: value.counter, max: value.max, testId: value.testId, unit: 'operations' };
90
+ }
91
+ export function classifyEars(statement) {
92
+ const s = statement.trim().replace(/\s+/g, ' ');
93
+ if ((s.match(/\bshall\b/gi) ?? []).length > 1 || (s.match(/しなければならない|してはならない|してはいけない|すること/g) ?? []).length > 1)
94
+ return null;
95
+ const english = /^(?:(.*,\s*(?:then\s+)?))?((?:the|a|an)\s+[^,]+?)\s+shall\s+(.+)$/i.exec(s);
96
+ if (english) {
97
+ const prefix = (english[1] ?? '').trim();
98
+ if (!english[3]?.replace(/^not\s*/i, '').replace(/[.!]/g, '').trim())
99
+ return null;
100
+ if (!prefix)
101
+ return 'ubiquitous';
102
+ if (/^if\s+.+,\s*then\s*$/i.test(prefix))
103
+ return 'unwanted-behavior';
104
+ const clauses = [...prefix.matchAll(/(?:^|,\s*)(while|when|where)\s+([^,]+)/gi)];
105
+ if (clauses.length && clauses.every((c) => c[2]?.trim())) {
106
+ const reconstructed = clauses.map((c) => `${c[1]} ${c[2]}`).join(', ');
107
+ if (reconstructed.toLowerCase() !== prefix.replace(/,\s*$/, '').toLowerCase())
108
+ return null;
109
+ const kinds = new Set(clauses.map((c) => c[1]?.toLowerCase()));
110
+ if (clauses.length > 1 && kinds.size > 1)
111
+ return 'complex';
112
+ if (clauses.length === 1) {
113
+ return { when: 'event-driven', while: 'state-driven', where: 'optional-feature' }[clauses[0]?.[1]?.toLowerCase()] ?? null;
114
+ }
115
+ }
116
+ return null;
117
+ }
118
+ // Japanese uses explicit control markers; free prose is deliberately not inferred.
119
+ const japanese = /^(.*?)システムは(.+?)(?:しなければならない|してはならない|してはいけない|すること)[。.]?$/.exec(s);
120
+ if (!japanese || !japanese[2]?.trim())
121
+ return null;
122
+ const prefix = japanese[1]?.trim() ?? '';
123
+ if (!prefix)
124
+ return 'ubiquitous';
125
+ if (/^もし.+ならば[、,]\s*$/.test(prefix))
126
+ return 'unwanted-behavior';
127
+ const clauses = prefix.split(/[、,]\s*/).filter(Boolean);
128
+ const kinds = clauses.map((c) => /.+とき$/.test(c) ? 'event-driven' : /.+間$/.test(c) ? 'state-driven' : /.+場合$/.test(c) ? 'optional-feature' : null);
129
+ if (kinds.some((k) => !k))
130
+ return null;
131
+ if (kinds.length > 1 && new Set(kinds).size > 1)
132
+ return 'complex';
133
+ return kinds.length === 1 ? kinds[0] : null;
134
+ }
135
+ export function validateRequirements(text, path = '<input>') {
136
+ const parsed = markdown(text, path);
137
+ const sections = parsed.sections.filter((s) => /^REQ-/i.test(s.id));
138
+ const diagnostics = [...parsed.diagnostics, ...duplicates(sections, path)];
139
+ if (parsed.metadata.schemaVersion !== undefined && parsed.metadata.schemaVersion !== 1)
140
+ diagnostics.push(error('REQ_SCHEMA', 'Unsupported schemaVersion; expected 1.', path));
141
+ if (!sections.length)
142
+ diagnostics.push(error('REQ_MISSING', 'No requirement headings found (## REQ-FEATURE-001: Title).', path));
143
+ const value = sections.map((section) => {
144
+ if (!ids.requirement.test(section.id))
145
+ diagnostics.push(error('REQ_ID', `Invalid requirement ID ${section.id}.`, path, section.line));
146
+ if (!section.title)
147
+ diagnostics.push(error('REQ_TITLE', 'Requirement title is required.', path, section.line));
148
+ const rawPriority = field(section.body, 'Priority|優先度').toLowerCase() || 'must';
149
+ if (!['must', 'should', 'may'].includes(rawPriority))
150
+ diagnostics.push(error('REQ_PRIORITY', 'Priority must be must, should, or may.', path, section.line));
151
+ const rawType = field(section.body, 'Type|種別').toLowerCase() || 'functional';
152
+ if (!['functional', 'non-functional'].includes(rawType)) {
153
+ diagnostics.push(error('REQ_TYPE', 'Requirement type must be functional or non-functional.', path, section.line));
154
+ }
155
+ const statement = field(section.body, 'Statement|要求') || section.body.split('\n')
156
+ .filter((line) => !/^\s*(?:[-*]\s+)?(?:\*\*)?(Priority|Type|Pattern|Acceptance|Formal|Performance|優先度|種別|パターン|受入条件|形式制約|性能予算)(?:\*\*)?\s*[::]/i.test(line))
157
+ .join(' ').trim();
158
+ const pattern = classifyEars(statement);
159
+ if (!pattern)
160
+ diagnostics.push(error('REQ_EARS', 'Use one complete controlled EARS statement with a subject, shall, response, and valid trigger/state/feature clause.', path, section.line));
161
+ const declared = field(section.body, 'Pattern|パターン').toLowerCase();
162
+ if (declared && declared !== pattern)
163
+ diagnostics.push(error('REQ_PATTERN', `Declared pattern ${declared} does not match detected pattern ${pattern ?? 'invalid'}.`, path, section.line));
164
+ const acceptance = field(section.body, 'Acceptance|受入条件');
165
+ const formal = parseFormal(field(section.body, 'Formal|形式制約'), path, section.line, diagnostics);
166
+ const performance = parsePerformance(field(section.body, 'Performance|性能予算'), path, section.line, diagnostics);
167
+ if (performance && rawType !== 'non-functional') {
168
+ diagnostics.push(error('REQ_PERFORMANCE_TYPE', 'Deterministic performance budgets are only valid on non-functional requirements.', path, section.line));
169
+ }
170
+ return {
171
+ id: section.id,
172
+ title: section.title,
173
+ priority: rawPriority,
174
+ type: rawType,
175
+ statement,
176
+ pattern,
177
+ acceptance,
178
+ formal,
179
+ performance,
180
+ line: section.line,
181
+ };
182
+ });
183
+ const statements = new Map();
184
+ for (const requirement of value) {
185
+ const normalized = requirement.statement.normalize('NFKC').toLowerCase().replace(/[。.!]/g, '').replace(/\s+/g, ' ').trim();
186
+ const previous = statements.get(normalized);
187
+ if (previous) {
188
+ diagnostics.push(error('REQ_DUPLICATE_STATEMENT', `${requirement.id} duplicates the normalized statement of ${previous.id}.`, path, requirement.line));
189
+ }
190
+ else
191
+ statements.set(normalized, requirement);
192
+ }
193
+ return validation(value, diagnostics);
194
+ }
195
+ //# sourceMappingURL=requirements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirements.js","sourceRoot":"","sources":["../../../../packages/domain/src/requirements.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ export type Severity = 'error' | 'warning';
2
+ export type CheckStatus = 'pass' | 'fail' | 'skipped';
3
+ export interface Diagnostic {
4
+ code: string;
5
+ severity: Severity;
6
+ message: string;
7
+ path?: string;
8
+ line?: number;
9
+ }
10
+ export interface Validation<T> {
11
+ valid: boolean;
12
+ value: T;
13
+ diagnostics: Diagnostic[];
14
+ }
15
+ export declare function validation<T>(value: T, diagnostics: Diagnostic[]): Validation<T>;
16
+ export declare function error(code: string, message: string, path?: string, line?: number): Diagnostic;
17
+ export declare const ids: {
18
+ requirement: RegExp;
19
+ design: RegExp;
20
+ code: RegExp;
21
+ test: RegExp;
22
+ adr: RegExp;
23
+ };
24
+ export interface Requirement {
25
+ id: string;
26
+ title: string;
27
+ statement: string;
28
+ acceptance: string;
29
+ priority: 'must' | 'should' | 'may';
30
+ type: 'functional' | 'non-functional';
31
+ pattern: EarsPattern | null;
32
+ formal: FormalConstraint | null;
33
+ performance: PerformanceBudget | null;
34
+ line: number;
35
+ }
36
+ export type EarsPattern = 'ubiquitous' | 'event-driven' | 'state-driven' | 'unwanted-behavior' | 'optional-feature' | 'complex';
37
+ export type FormalConstraint = {
38
+ kind: 'conditional';
39
+ condition: string;
40
+ consequence: string;
41
+ conditionValue: boolean;
42
+ consequenceValue: boolean;
43
+ } | {
44
+ kind: 'numeric';
45
+ metric: string;
46
+ operator: '<' | '<=' | '=' | '>=' | '>';
47
+ value: number;
48
+ unit?: string;
49
+ } | {
50
+ kind: 'temporal';
51
+ trigger: string;
52
+ response: string;
53
+ withinMs: number;
54
+ afterMs?: number;
55
+ } | {
56
+ kind: 'transition';
57
+ from: string;
58
+ event: string;
59
+ to: string;
60
+ };
61
+ export interface PerformanceBudget {
62
+ counter: string;
63
+ max: number;
64
+ testId: string;
65
+ unit: 'operations';
66
+ }
67
+ export interface Component {
68
+ id: string;
69
+ title: string;
70
+ responsibility: string;
71
+ interfaces: string;
72
+ constraints: string;
73
+ requirements: string[];
74
+ decisions: string[];
75
+ dependencies: string[];
76
+ line: number;
77
+ }
78
+ export interface ConstitutionRule {
79
+ id: string;
80
+ principle: string;
81
+ metric: string;
82
+ limit: number;
83
+ line: number;
84
+ }
85
+ export interface Constitution {
86
+ version: string;
87
+ principles: string[];
88
+ rules: ConstitutionRule[];
89
+ }
90
+ export interface Evidence {
91
+ name: string;
92
+ status: CheckStatus;
93
+ required: boolean;
94
+ summary: string;
95
+ diagnostics?: Diagnostic[];
96
+ durationMs?: number;
97
+ exitCode?: number | null;
98
+ stdout?: string;
99
+ stderr?: string;
100
+ }
@@ -0,0 +1,14 @@
1
+ export function validation(value, diagnostics) {
2
+ return { valid: !diagnostics.some((d) => d.severity === 'error'), value, diagnostics };
3
+ }
4
+ export function error(code, message, path, line) {
5
+ return { code, severity: 'error', message, ...(path ? { path } : {}), ...(line ? { line } : {}) };
6
+ }
7
+ export const ids = {
8
+ requirement: /^REQ-[A-Z0-9]+(?:-[A-Z0-9]+)*-\d{3,}$/,
9
+ design: /^DES-[A-Z0-9]+(?:-[A-Z0-9]+)*-\d{3,}$/,
10
+ code: /^CODE-[A-Z0-9]+(?:-[A-Z0-9]+)*-\d{3,}$/,
11
+ test: /^TEST-[A-Z0-9]+(?:-[A-Z0-9]+)*-\d{3,}$/,
12
+ adr: /^ADR-\d{4,}$/,
13
+ };
14
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../packages/domain/src/types.ts"],"names":[],"mappings":"AAiBA,MAAM,UAAU,UAAU,CAAI,KAAQ,EAAE,WAAyB;IAC/D,OAAO,EAAE,KAAK,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,OAAe,EAAE,IAAa,EAAE,IAAa;IAC/E,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACpG,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,WAAW,EAAE,uCAAuC;IACpD,MAAM,EAAE,uCAAuC;IAC/C,IAAI,EAAE,wCAAwC;IAC9C,IAAI,EAAE,wCAAwC;IAC9C,GAAG,EAAE,cAAc;CACpB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "musubix3",
3
+ "version": "0.1.0",
4
+ "description": "Evidence-driven specification development skills for GitHub Copilot CLI",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "nahisaho",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/nahisaho/musubix3.git"
11
+ },
12
+ "engines": {
13
+ "node": ">=20"
14
+ },
15
+ "workspaces": [
16
+ "packages/*"
17
+ ],
18
+ "bin": {
19
+ "musubix3": "dist/packages/cli/src/main.js"
20
+ },
21
+ "exports": {
22
+ "./domain": "./dist/packages/domain/src/index.js",
23
+ "./analysis": "./dist/packages/analysis/src/index.js",
24
+ "./attestation": "./dist/packages/analysis/src/attestation.js"
25
+ },
26
+ "files": [
27
+ "dist",
28
+ "assets",
29
+ ".github/skills",
30
+ ".github/plugin/marketplace.json",
31
+ "plugin.json",
32
+ "README-ja.md",
33
+ "CHANGELOG.md",
34
+ "LICENSE"
35
+ ],
36
+ "scripts": {
37
+ "build": "tsc -p tsconfig.build.json",
38
+ "typecheck": "tsc --noEmit",
39
+ "test": "vitest run",
40
+ "test:adapters": "vitest run tests/adapter-integration.test.ts --maxWorkers=1",
41
+ "test:watch": "vitest",
42
+ "pack:check": "node scripts/check-package.mjs",
43
+ "pack:smoke": "node scripts/smoke-package.mjs",
44
+ "release:prepare": "node scripts/release-prepare.mjs",
45
+ "release:attest": "node scripts/release-attestation.mjs",
46
+ "release:publish": "node scripts/release-publish.mjs",
47
+ "prepack": "npm run build"
48
+ },
49
+ "dependencies": {
50
+ "commander": "^13.1.0",
51
+ "typescript": "~5.9.3",
52
+ "yaml": "^2.8.1"
53
+ },
54
+ "devDependencies": {
55
+ "@types/node": "^22.19.0",
56
+ "jest": "^30.5.1",
57
+ "vitest": "^3.2.4"
58
+ }
59
+ }
package/plugin.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "musubix3",
3
+ "version": "0.1.0",
4
+ "description": "Evidence-driven SDD skills for GitHub Copilot CLI: requirements, design, traceability, implementation, quality, knowledge, formal checks and codegraph.",
5
+ "author": { "name": "nahisaho" },
6
+ "repository": "https://github.com/nahisaho/musubix3",
7
+ "license": "MIT",
8
+ "skills": ".github/skills/"
9
+ }