@specship/specship-win32-arm64 0.21.2 → 0.22.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 (96) hide show
  1. package/lib/dist/bin/specship.js +302 -4
  2. package/lib/dist/bin/specship.js.map +1 -1
  3. package/lib/dist/commands/specship/jira.md +74 -0
  4. package/lib/dist/commands/specship/spec.md +61 -1
  5. package/lib/dist/extraction/index.d.ts +6 -0
  6. package/lib/dist/extraction/index.d.ts.map +1 -1
  7. package/lib/dist/extraction/index.js.map +1 -1
  8. package/lib/dist/extraction/specs/markdown-spec-extractor.d.ts.map +1 -1
  9. package/lib/dist/extraction/specs/markdown-spec-extractor.js +8 -1
  10. package/lib/dist/extraction/specs/markdown-spec-extractor.js.map +1 -1
  11. package/lib/dist/index.d.ts +7 -0
  12. package/lib/dist/index.d.ts.map +1 -1
  13. package/lib/dist/index.js +45 -18
  14. package/lib/dist/index.js.map +1 -1
  15. package/lib/dist/jira/auto-publish.d.ts +67 -0
  16. package/lib/dist/jira/auto-publish.d.ts.map +1 -0
  17. package/lib/dist/jira/auto-publish.js +232 -0
  18. package/lib/dist/jira/auto-publish.js.map +1 -0
  19. package/lib/dist/jira/board-first.d.ts +64 -0
  20. package/lib/dist/jira/board-first.d.ts.map +1 -0
  21. package/lib/dist/jira/board-first.js +91 -0
  22. package/lib/dist/jira/board-first.js.map +1 -0
  23. package/lib/dist/jira/client.d.ts +80 -1
  24. package/lib/dist/jira/client.d.ts.map +1 -1
  25. package/lib/dist/jira/client.js +213 -1
  26. package/lib/dist/jira/client.js.map +1 -1
  27. package/lib/dist/jira/config.d.ts +1 -1
  28. package/lib/dist/jira/config.d.ts.map +1 -1
  29. package/lib/dist/jira/config.js +14 -3
  30. package/lib/dist/jira/config.js.map +1 -1
  31. package/lib/dist/jira/coverage.d.ts +105 -0
  32. package/lib/dist/jira/coverage.d.ts.map +1 -0
  33. package/lib/dist/jira/coverage.js +160 -0
  34. package/lib/dist/jira/coverage.js.map +1 -0
  35. package/lib/dist/jira/index.d.ts +1 -0
  36. package/lib/dist/jira/index.d.ts.map +1 -1
  37. package/lib/dist/jira/index.js +1 -0
  38. package/lib/dist/jira/index.js.map +1 -1
  39. package/lib/dist/jira/milestone-comment.d.ts +95 -0
  40. package/lib/dist/jira/milestone-comment.d.ts.map +1 -0
  41. package/lib/dist/jira/milestone-comment.js +271 -0
  42. package/lib/dist/jira/milestone-comment.js.map +1 -0
  43. package/lib/dist/jira/publish.d.ts +69 -2
  44. package/lib/dist/jira/publish.d.ts.map +1 -1
  45. package/lib/dist/jira/publish.js +0 -0
  46. package/lib/dist/jira/publish.js.map +1 -1
  47. package/lib/dist/jira/published-specs.d.ts +23 -0
  48. package/lib/dist/jira/published-specs.d.ts.map +1 -0
  49. package/lib/dist/jira/published-specs.js +106 -0
  50. package/lib/dist/jira/published-specs.js.map +1 -0
  51. package/lib/dist/jira/reconcile.d.ts +81 -0
  52. package/lib/dist/jira/reconcile.d.ts.map +1 -0
  53. package/lib/dist/jira/reconcile.js +111 -0
  54. package/lib/dist/jira/reconcile.js.map +1 -0
  55. package/lib/dist/jira/regression-pack.d.ts +547 -0
  56. package/lib/dist/jira/regression-pack.d.ts.map +1 -0
  57. package/lib/dist/jira/regression-pack.js +986 -0
  58. package/lib/dist/jira/regression-pack.js.map +1 -0
  59. package/lib/dist/jira/repo-config.d.ts +59 -0
  60. package/lib/dist/jira/repo-config.d.ts.map +1 -0
  61. package/lib/dist/jira/repo-config.js +222 -0
  62. package/lib/dist/jira/repo-config.js.map +1 -0
  63. package/lib/dist/jira/spec-amend.d.ts +46 -0
  64. package/lib/dist/jira/spec-amend.d.ts.map +1 -0
  65. package/lib/dist/jira/spec-amend.js +232 -0
  66. package/lib/dist/jira/spec-amend.js.map +1 -0
  67. package/lib/dist/jira/spec-writer.d.ts +22 -0
  68. package/lib/dist/jira/spec-writer.d.ts.map +1 -1
  69. package/lib/dist/jira/spec-writer.js +113 -0
  70. package/lib/dist/jira/spec-writer.js.map +1 -1
  71. package/lib/dist/jira/types.d.ts +62 -0
  72. package/lib/dist/jira/types.d.ts.map +1 -1
  73. package/lib/dist/jira/types.js +15 -1
  74. package/lib/dist/jira/types.js.map +1 -1
  75. package/lib/dist/mcp/jira-tools.d.ts +102 -0
  76. package/lib/dist/mcp/jira-tools.d.ts.map +1 -1
  77. package/lib/dist/mcp/jira-tools.js +807 -50
  78. package/lib/dist/mcp/jira-tools.js.map +1 -1
  79. package/lib/dist/mcp/server-instructions.d.ts +1 -1
  80. package/lib/dist/mcp/server-instructions.d.ts.map +1 -1
  81. package/lib/dist/mcp/server-instructions.js +4 -0
  82. package/lib/dist/mcp/server-instructions.js.map +1 -1
  83. package/lib/dist/mcp/spec-tools.d.ts.map +1 -1
  84. package/lib/dist/mcp/spec-tools.js +7 -1
  85. package/lib/dist/mcp/spec-tools.js.map +1 -1
  86. package/lib/dist/mcp/tools.d.ts +3 -0
  87. package/lib/dist/mcp/tools.d.ts.map +1 -1
  88. package/lib/dist/mcp/tools.js +50 -0
  89. package/lib/dist/mcp/tools.js.map +1 -1
  90. package/lib/dist/resolution/spec-link-resolver.d.ts +2 -0
  91. package/lib/dist/resolution/spec-link-resolver.d.ts.map +1 -1
  92. package/lib/dist/resolution/spec-link-resolver.js +11 -3
  93. package/lib/dist/resolution/spec-link-resolver.js.map +1 -1
  94. package/lib/node_modules/.package-lock.json +1 -1
  95. package/lib/package.json +1 -1
  96. package/package.json +1 -1
@@ -0,0 +1,81 @@
1
+ /**
2
+ * JIRA-side edit reconciliation (REQ-JIRATEAM-005).
3
+ *
4
+ * Pure diff: given a live JIRA issue, its published fingerprint (stored in the
5
+ * spec's frontmatter), and the parsed spec, report divergences without any I/O
6
+ * so the module is testable without MCP/JIRA plumbing. Two flavors:
7
+ * - content divergence: the issue's summary/description was edited in JIRA
8
+ * after publish (fingerprint mismatch);
9
+ * - subtask divergence: a Sub-task was added in JIRA that has no matching
10
+ * acceptance criterion — reported with a proposed `.A<N+1>` id and text
11
+ * derived from the Sub-task summary.
12
+ *
13
+ * Sub-task matching reuses `subtaskSummary()` from `./publish` so the
14
+ * comparison uses the EXACT same one-line truncation the publisher wrote
15
+ * with — a Sub-task that publish wrote is never re-proposed on the way back.
16
+ */
17
+ import type { JiraIssue } from './types';
18
+ export interface SubtaskDivergence {
19
+ subtaskKey: string;
20
+ subtaskSummary: string;
21
+ /** Proposed `.A<N>` id (the next available under the requirement). */
22
+ proposedCriterionId: string;
23
+ /** Proposed criterion text derived from the Sub-task summary. */
24
+ proposedCriterionText: string;
25
+ }
26
+ export interface ContentDivergence {
27
+ issueKey: string;
28
+ liveSummary: string;
29
+ liveDescription: string;
30
+ storedFingerprint: string;
31
+ liveFingerprint: string;
32
+ }
33
+ export interface ReconcileReport {
34
+ specRelPath: string;
35
+ issueKey: string;
36
+ /** The requirement's spec id (e.g. `REQ-AUTH-001`) the divergences belong to. */
37
+ requirementId: string;
38
+ content?: ContentDivergence;
39
+ subtasks: SubtaskDivergence[];
40
+ }
41
+ /**
42
+ * True when the report has any divergence to show. A clean report (no content
43
+ * mismatch, no orphan Sub-task) is not surfaced to the user.
44
+ */
45
+ export declare function reportHasDivergence(report: ReconcileReport): boolean;
46
+ /**
47
+ * The next `.A<N>` id after the largest existing suffix under `requirementId`.
48
+ * Tolerates gaps and out-of-order ids: `[.A1, .A3]` yields `.A4`; empty → `.A1`.
49
+ * Non-`.A<N>` ids and ids under other requirements are ignored.
50
+ */
51
+ export declare function nextAcceptanceId(requirementId: string, existingIds: readonly string[]): string;
52
+ /**
53
+ * Turn a Sub-task summary into acceptance-criterion body text — one line,
54
+ * trailing punctuation kept, no truncation (unlike the publish-side summary,
55
+ * which caps at 240 for the JIRA field limit).
56
+ */
57
+ export declare function proposeCriterionFromSubtask(summary: string): string;
58
+ /**
59
+ * Data a caller supplies about a published spec — enough to diff. `title` and
60
+ * `body` are what publish would send today (kept in-memory by the caller so
61
+ * this module doesn't have to parse the spec file itself).
62
+ */
63
+ export interface SpecViewForDiff {
64
+ specRelPath: string;
65
+ requirementId: string;
66
+ title: string;
67
+ body: string;
68
+ acceptance: Array<{
69
+ id: string;
70
+ text: string;
71
+ }>;
72
+ }
73
+ /**
74
+ * Diff a live JIRA issue against its published spec. `storedFingerprint` is the
75
+ * `jira_fingerprint:` recorded in the spec's frontmatter at publish time; when
76
+ * null, the content divergence check is skipped (we can't judge drift without
77
+ * a baseline). Sub-tasks whose summaries match any existing acceptance
78
+ * criterion under `subtaskSummary()` are considered in-sync.
79
+ */
80
+ export declare function diffIssueVsSpec(issue: JiraIssue, spec: SpecViewForDiff, storedFingerprint: string | null): ReconcileReport;
81
+ //# sourceMappingURL=reconcile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/jira/reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,sEAAsE;IACtE,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAEpE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,MAAM,CASR;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,eAAe,EACrB,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAC/B,eAAe,CAkDjB"}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ /**
3
+ * JIRA-side edit reconciliation (REQ-JIRATEAM-005).
4
+ *
5
+ * Pure diff: given a live JIRA issue, its published fingerprint (stored in the
6
+ * spec's frontmatter), and the parsed spec, report divergences without any I/O
7
+ * so the module is testable without MCP/JIRA plumbing. Two flavors:
8
+ * - content divergence: the issue's summary/description was edited in JIRA
9
+ * after publish (fingerprint mismatch);
10
+ * - subtask divergence: a Sub-task was added in JIRA that has no matching
11
+ * acceptance criterion — reported with a proposed `.A<N+1>` id and text
12
+ * derived from the Sub-task summary.
13
+ *
14
+ * Sub-task matching reuses `subtaskSummary()` from `./publish` so the
15
+ * comparison uses the EXACT same one-line truncation the publisher wrote
16
+ * with — a Sub-task that publish wrote is never re-proposed on the way back.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.reportHasDivergence = reportHasDivergence;
20
+ exports.nextAcceptanceId = nextAcceptanceId;
21
+ exports.proposeCriterionFromSubtask = proposeCriterionFromSubtask;
22
+ exports.diffIssueVsSpec = diffIssueVsSpec;
23
+ const publish_1 = require("./publish");
24
+ /**
25
+ * True when the report has any divergence to show. A clean report (no content
26
+ * mismatch, no orphan Sub-task) is not surfaced to the user.
27
+ */
28
+ function reportHasDivergence(report) {
29
+ return Boolean(report.content) || report.subtasks.length > 0;
30
+ }
31
+ /**
32
+ * The next `.A<N>` id after the largest existing suffix under `requirementId`.
33
+ * Tolerates gaps and out-of-order ids: `[.A1, .A3]` yields `.A4`; empty → `.A1`.
34
+ * Non-`.A<N>` ids and ids under other requirements are ignored.
35
+ */
36
+ function nextAcceptanceId(requirementId, existingIds) {
37
+ const prefix = `${requirementId}.A`;
38
+ let max = 0;
39
+ for (const id of existingIds) {
40
+ if (!id.startsWith(prefix))
41
+ continue;
42
+ const n = Number(id.slice(prefix.length));
43
+ if (Number.isFinite(n) && n > max)
44
+ max = n;
45
+ }
46
+ return `${requirementId}.A${max + 1}`;
47
+ }
48
+ /**
49
+ * Turn a Sub-task summary into acceptance-criterion body text — one line,
50
+ * trailing punctuation kept, no truncation (unlike the publish-side summary,
51
+ * which caps at 240 for the JIRA field limit).
52
+ */
53
+ function proposeCriterionFromSubtask(summary) {
54
+ return summary.replace(/\s+/g, ' ').trim();
55
+ }
56
+ /**
57
+ * Diff a live JIRA issue against its published spec. `storedFingerprint` is the
58
+ * `jira_fingerprint:` recorded in the spec's frontmatter at publish time; when
59
+ * null, the content divergence check is skipped (we can't judge drift without
60
+ * a baseline). Sub-tasks whose summaries match any existing acceptance
61
+ * criterion under `subtaskSummary()` are considered in-sync.
62
+ */
63
+ function diffIssueVsSpec(issue, spec, storedFingerprint) {
64
+ const report = {
65
+ specRelPath: spec.specRelPath,
66
+ issueKey: issue.key,
67
+ requirementId: spec.requirementId,
68
+ subtasks: [],
69
+ };
70
+ // Content divergence (REQ-JIRATEAM-005.A1). The publisher's fingerprint is
71
+ // over (summary, description); we recompute the LIVE fingerprint and compare.
72
+ if (storedFingerprint) {
73
+ const liveSummary = issue.summary ?? '';
74
+ const liveDescription = issue.description ?? '';
75
+ const liveFp = (0, publish_1.issueContentFingerprint)(liveSummary, liveDescription);
76
+ if (liveFp !== storedFingerprint) {
77
+ report.content = {
78
+ issueKey: issue.key,
79
+ liveSummary,
80
+ liveDescription,
81
+ storedFingerprint,
82
+ liveFingerprint: liveFp,
83
+ };
84
+ }
85
+ }
86
+ // Sub-task divergence (REQ-JIRATEAM-005.A2). Reuse subtaskSummary() so the
87
+ // comparison uses the EXACT same one-line truncation the publisher wrote
88
+ // with — a Sub-task publish itself wrote can never look "new" on the way
89
+ // back.
90
+ const knownSummaries = new Set(spec.acceptance.map((a) => (0, publish_1.subtaskSummary)(a.text)));
91
+ const existingIds = spec.acceptance.map((a) => a.id);
92
+ let nextId = nextAcceptanceId(spec.requirementId, existingIds);
93
+ for (const st of issue.subtasks ?? []) {
94
+ const summary = (0, publish_1.subtaskSummary)(st.summary ?? '');
95
+ if (!summary)
96
+ continue;
97
+ if (knownSummaries.has(summary))
98
+ continue;
99
+ report.subtasks.push({
100
+ subtaskKey: st.key,
101
+ subtaskSummary: st.summary,
102
+ proposedCriterionId: nextId,
103
+ proposedCriterionText: proposeCriterionFromSubtask(st.summary),
104
+ });
105
+ // Reserve the id we just proposed for the next iteration.
106
+ const n = Number(nextId.slice(`${spec.requirementId}.A`.length)) + 1;
107
+ nextId = `${spec.requirementId}.A${n}`;
108
+ }
109
+ return report;
110
+ }
111
+ //# sourceMappingURL=reconcile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/jira/reconcile.ts"],"names":[],"mappings":"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"}