@stoneforge/quarry 1.12.0 → 1.14.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/README.md +2 -0
- package/dist/api/quarry-api.d.ts +9 -1
- package/dist/api/quarry-api.d.ts.map +1 -1
- package/dist/api/quarry-api.js +21 -2
- package/dist/api/quarry-api.js.map +1 -1
- package/dist/api/types.d.ts +8 -1
- package/dist/api/types.d.ts.map +1 -1
- package/dist/api/types.js.map +1 -1
- package/dist/cli/commands/auto-link-helper.d.ts +33 -0
- package/dist/cli/commands/auto-link-helper.d.ts.map +1 -0
- package/dist/cli/commands/auto-link-helper.js +74 -0
- package/dist/cli/commands/auto-link-helper.js.map +1 -0
- package/dist/cli/commands/crud.d.ts +3 -0
- package/dist/cli/commands/crud.d.ts.map +1 -1
- package/dist/cli/commands/crud.js +144 -15
- package/dist/cli/commands/crud.js.map +1 -1
- package/dist/cli/commands/docs.js +2 -2
- package/dist/cli/commands/docs.js.map +1 -1
- package/dist/cli/commands/document.js +1 -1
- package/dist/cli/commands/document.js.map +1 -1
- package/dist/cli/commands/entity.js +1 -1
- package/dist/cli/commands/entity.js.map +1 -1
- package/dist/cli/commands/external-sync.d.ts +18 -0
- package/dist/cli/commands/external-sync.d.ts.map +1 -0
- package/dist/cli/commands/external-sync.js +2499 -0
- package/dist/cli/commands/external-sync.js.map +1 -0
- package/dist/cli/commands/library.js +1 -1
- package/dist/cli/commands/library.js.map +1 -1
- package/dist/cli/commands/message.js +2 -2
- package/dist/cli/commands/message.js.map +1 -1
- package/dist/cli/commands/serve.d.ts.map +1 -1
- package/dist/cli/commands/serve.js +2 -0
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/task.d.ts.map +1 -1
- package/dist/cli/commands/task.js +7 -4
- package/dist/cli/commands/task.js.map +1 -1
- package/dist/cli/commands/team.js +1 -1
- package/dist/cli/commands/team.js.map +1 -1
- package/dist/cli/commands/workflow.js +1 -1
- package/dist/cli/commands/workflow.js.map +1 -1
- package/dist/cli/runner.d.ts.map +1 -1
- package/dist/cli/runner.js +3 -0
- package/dist/cli/runner.js.map +1 -1
- package/dist/cli/utils/progress.d.ts +30 -0
- package/dist/cli/utils/progress.d.ts.map +1 -0
- package/dist/cli/utils/progress.js +47 -0
- package/dist/cli/utils/progress.js.map +1 -0
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +34 -0
- package/dist/config/config.js.map +1 -1
- package/dist/config/defaults.d.ts +13 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +22 -0
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/file.d.ts.map +1 -1
- package/dist/config/file.js +71 -0
- package/dist/config/file.js.map +1 -1
- package/dist/config/index.d.ts +3 -3
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +2 -2
- package/dist/config/index.js.map +1 -1
- package/dist/config/merge.d.ts.map +1 -1
- package/dist/config/merge.js +52 -1
- package/dist/config/merge.js.map +1 -1
- package/dist/config/types.d.ts +68 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +33 -0
- package/dist/config/types.js.map +1 -1
- package/dist/config/validation.d.ts.map +1 -1
- package/dist/config/validation.js +64 -1
- package/dist/config/validation.js.map +1 -1
- package/dist/external-sync/adapters/document-sync-adapter.d.ts +150 -0
- package/dist/external-sync/adapters/document-sync-adapter.d.ts.map +1 -0
- package/dist/external-sync/adapters/document-sync-adapter.js +325 -0
- package/dist/external-sync/adapters/document-sync-adapter.js.map +1 -0
- package/dist/external-sync/adapters/task-sync-adapter.d.ts +177 -0
- package/dist/external-sync/adapters/task-sync-adapter.d.ts.map +1 -0
- package/dist/external-sync/adapters/task-sync-adapter.js +353 -0
- package/dist/external-sync/adapters/task-sync-adapter.js.map +1 -0
- package/dist/external-sync/auto-link.d.ts +66 -0
- package/dist/external-sync/auto-link.d.ts.map +1 -0
- package/dist/external-sync/auto-link.js +98 -0
- package/dist/external-sync/auto-link.js.map +1 -0
- package/dist/external-sync/conflict-resolver.d.ts +170 -0
- package/dist/external-sync/conflict-resolver.d.ts.map +1 -0
- package/dist/external-sync/conflict-resolver.js +580 -0
- package/dist/external-sync/conflict-resolver.js.map +1 -0
- package/dist/external-sync/index.d.ts +23 -0
- package/dist/external-sync/index.d.ts.map +1 -0
- package/dist/external-sync/index.js +24 -0
- package/dist/external-sync/index.js.map +1 -0
- package/dist/external-sync/provider-registry.d.ts +113 -0
- package/dist/external-sync/provider-registry.d.ts.map +1 -0
- package/dist/external-sync/provider-registry.js +205 -0
- package/dist/external-sync/provider-registry.js.map +1 -0
- package/dist/external-sync/providers/folder/folder-document-adapter.d.ts +97 -0
- package/dist/external-sync/providers/folder/folder-document-adapter.d.ts.map +1 -0
- package/dist/external-sync/providers/folder/folder-document-adapter.js +261 -0
- package/dist/external-sync/providers/folder/folder-document-adapter.js.map +1 -0
- package/dist/external-sync/providers/folder/folder-fs.d.ts +146 -0
- package/dist/external-sync/providers/folder/folder-fs.d.ts.map +1 -0
- package/dist/external-sync/providers/folder/folder-fs.js +300 -0
- package/dist/external-sync/providers/folder/folder-fs.js.map +1 -0
- package/dist/external-sync/providers/folder/folder-provider.d.ts +28 -0
- package/dist/external-sync/providers/folder/folder-provider.d.ts.map +1 -0
- package/dist/external-sync/providers/folder/folder-provider.js +87 -0
- package/dist/external-sync/providers/folder/folder-provider.js.map +1 -0
- package/dist/external-sync/providers/folder/index.d.ts +11 -0
- package/dist/external-sync/providers/folder/index.d.ts.map +1 -0
- package/dist/external-sync/providers/folder/index.js +13 -0
- package/dist/external-sync/providers/folder/index.js.map +1 -0
- package/dist/external-sync/providers/github/github-api.d.ts +271 -0
- package/dist/external-sync/providers/github/github-api.d.ts.map +1 -0
- package/dist/external-sync/providers/github/github-api.js +366 -0
- package/dist/external-sync/providers/github/github-api.js.map +1 -0
- package/dist/external-sync/providers/github/github-field-map.d.ts +76 -0
- package/dist/external-sync/providers/github/github-field-map.d.ts.map +1 -0
- package/dist/external-sync/providers/github/github-field-map.js +157 -0
- package/dist/external-sync/providers/github/github-field-map.js.map +1 -0
- package/dist/external-sync/providers/github/github-provider.d.ts +36 -0
- package/dist/external-sync/providers/github/github-provider.d.ts.map +1 -0
- package/dist/external-sync/providers/github/github-provider.js +212 -0
- package/dist/external-sync/providers/github/github-provider.js.map +1 -0
- package/dist/external-sync/providers/github/github-task-adapter.d.ts +135 -0
- package/dist/external-sync/providers/github/github-task-adapter.d.ts.map +1 -0
- package/dist/external-sync/providers/github/github-task-adapter.js +374 -0
- package/dist/external-sync/providers/github/github-task-adapter.js.map +1 -0
- package/dist/external-sync/providers/github/index.d.ts +12 -0
- package/dist/external-sync/providers/github/index.d.ts.map +1 -0
- package/dist/external-sync/providers/github/index.js +15 -0
- package/dist/external-sync/providers/github/index.js.map +1 -0
- package/dist/external-sync/providers/index.d.ts +13 -0
- package/dist/external-sync/providers/index.d.ts.map +1 -0
- package/dist/external-sync/providers/index.js +15 -0
- package/dist/external-sync/providers/index.js.map +1 -0
- package/dist/external-sync/providers/linear/index.d.ts +19 -0
- package/dist/external-sync/providers/linear/index.d.ts.map +1 -0
- package/dist/external-sync/providers/linear/index.js +19 -0
- package/dist/external-sync/providers/linear/index.js.map +1 -0
- package/dist/external-sync/providers/linear/linear-api.d.ts +252 -0
- package/dist/external-sync/providers/linear/linear-api.d.ts.map +1 -0
- package/dist/external-sync/providers/linear/linear-api.js +522 -0
- package/dist/external-sync/providers/linear/linear-api.js.map +1 -0
- package/dist/external-sync/providers/linear/linear-field-map.d.ts +135 -0
- package/dist/external-sync/providers/linear/linear-field-map.d.ts.map +1 -0
- package/dist/external-sync/providers/linear/linear-field-map.js +338 -0
- package/dist/external-sync/providers/linear/linear-field-map.js.map +1 -0
- package/dist/external-sync/providers/linear/linear-provider.d.ts +52 -0
- package/dist/external-sync/providers/linear/linear-provider.d.ts.map +1 -0
- package/dist/external-sync/providers/linear/linear-provider.js +169 -0
- package/dist/external-sync/providers/linear/linear-provider.js.map +1 -0
- package/dist/external-sync/providers/linear/linear-task-adapter.d.ts +190 -0
- package/dist/external-sync/providers/linear/linear-task-adapter.d.ts.map +1 -0
- package/dist/external-sync/providers/linear/linear-task-adapter.js +521 -0
- package/dist/external-sync/providers/linear/linear-task-adapter.js.map +1 -0
- package/dist/external-sync/providers/linear/linear-types.d.ts +114 -0
- package/dist/external-sync/providers/linear/linear-types.d.ts.map +1 -0
- package/dist/external-sync/providers/linear/linear-types.js +10 -0
- package/dist/external-sync/providers/linear/linear-types.js.map +1 -0
- package/dist/external-sync/providers/notion/index.d.ts +19 -0
- package/dist/external-sync/providers/notion/index.d.ts.map +1 -0
- package/dist/external-sync/providers/notion/index.js +20 -0
- package/dist/external-sync/providers/notion/index.js.map +1 -0
- package/dist/external-sync/providers/notion/notion-api.d.ts +253 -0
- package/dist/external-sync/providers/notion/notion-api.d.ts.map +1 -0
- package/dist/external-sync/providers/notion/notion-api.js +492 -0
- package/dist/external-sync/providers/notion/notion-api.js.map +1 -0
- package/dist/external-sync/providers/notion/notion-blocks.d.ts +93 -0
- package/dist/external-sync/providers/notion/notion-blocks.d.ts.map +1 -0
- package/dist/external-sync/providers/notion/notion-blocks.js +773 -0
- package/dist/external-sync/providers/notion/notion-blocks.js.map +1 -0
- package/dist/external-sync/providers/notion/notion-document-adapter.d.ts +176 -0
- package/dist/external-sync/providers/notion/notion-document-adapter.d.ts.map +1 -0
- package/dist/external-sync/providers/notion/notion-document-adapter.js +413 -0
- package/dist/external-sync/providers/notion/notion-document-adapter.js.map +1 -0
- package/dist/external-sync/providers/notion/notion-provider.d.ts +57 -0
- package/dist/external-sync/providers/notion/notion-provider.d.ts.map +1 -0
- package/dist/external-sync/providers/notion/notion-provider.js +159 -0
- package/dist/external-sync/providers/notion/notion-provider.js.map +1 -0
- package/dist/external-sync/providers/notion/notion-types.d.ts +388 -0
- package/dist/external-sync/providers/notion/notion-types.d.ts.map +1 -0
- package/dist/external-sync/providers/notion/notion-types.js +47 -0
- package/dist/external-sync/providers/notion/notion-types.js.map +1 -0
- package/dist/external-sync/sync-engine.d.ts +364 -0
- package/dist/external-sync/sync-engine.d.ts.map +1 -0
- package/dist/external-sync/sync-engine.js +1154 -0
- package/dist/external-sync/sync-engine.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/server/index.js +8 -8
- package/dist/server/index.js.map +1 -1
- package/dist/services/inbox.js +1 -1
- package/dist/sync/hash.d.ts +5 -0
- package/dist/sync/hash.d.ts.map +1 -1
- package/dist/sync/hash.js +21 -2
- package/dist/sync/hash.js.map +1 -1
- package/package.json +10 -12
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linear Field Mapping Configuration
|
|
3
|
+
*
|
|
4
|
+
* Defines how Stoneforge task fields map to Linear issue fields.
|
|
5
|
+
*
|
|
6
|
+
* Key differences from GitHub:
|
|
7
|
+
* - Linear has native priority (0-4) — no label-based priority convention needed
|
|
8
|
+
* - Linear has workflow state types — status mapping uses state types, not labels
|
|
9
|
+
* - Task types use the same label convention as GitHub (type:bug, etc.)
|
|
10
|
+
*
|
|
11
|
+
* Priority mapping (Linear 0-4 ↔ Stoneforge 1-5):
|
|
12
|
+
* Linear 1 (Urgent) ↔ Stoneforge 1 (critical)
|
|
13
|
+
* Linear 2 (High) ↔ Stoneforge 2 (high)
|
|
14
|
+
* Linear 3 (Medium) ↔ Stoneforge 3 (medium)
|
|
15
|
+
* Linear 4 (Low) ↔ Stoneforge 4 (low)
|
|
16
|
+
* Linear 0 (No priority) ↔ Stoneforge 5 (minimal)
|
|
17
|
+
*
|
|
18
|
+
* Status mapping via workflow state TYPE (not name):
|
|
19
|
+
* Pull: triage/backlog → backlog, unstarted → open, started → in_progress,
|
|
20
|
+
* completed → closed, canceled → closed (closeReason: "canceled")
|
|
21
|
+
* Push: open → unstarted, in_progress/review → started,
|
|
22
|
+
* blocked → started (add "blocked" label), deferred/backlog → backlog,
|
|
23
|
+
* closed → completed
|
|
24
|
+
*/
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Status Label Mapping (for adapter-injected status labels)
|
|
27
|
+
// ============================================================================
|
|
28
|
+
/**
|
|
29
|
+
* Maps Stoneforge TaskStatus values to label strings.
|
|
30
|
+
* Linear doesn't natively use label-based status, but the adapter injects
|
|
31
|
+
* sf:status:* labels into ExternalTask.labels to communicate granular workflow
|
|
32
|
+
* state types through the generic field mapping system.
|
|
33
|
+
*
|
|
34
|
+
* This keeps the sync engine provider-agnostic — it reads status from labels
|
|
35
|
+
* the same way for both GitHub (user-managed labels) and Linear (adapter-injected).
|
|
36
|
+
*/
|
|
37
|
+
export const LINEAR_STATUS_LABELS = {
|
|
38
|
+
open: 'status:open',
|
|
39
|
+
in_progress: 'status:in-progress',
|
|
40
|
+
blocked: 'status:blocked',
|
|
41
|
+
deferred: 'status:deferred',
|
|
42
|
+
backlog: 'status:backlog',
|
|
43
|
+
review: 'status:review',
|
|
44
|
+
closed: 'status:closed',
|
|
45
|
+
tombstone: 'status:tombstone',
|
|
46
|
+
};
|
|
47
|
+
// ============================================================================
|
|
48
|
+
// Priority Mapping
|
|
49
|
+
// ============================================================================
|
|
50
|
+
/**
|
|
51
|
+
* Maps Stoneforge priority (1-5) to Linear priority (0-4).
|
|
52
|
+
*
|
|
53
|
+
* Stoneforge 1 (critical) → Linear 1 (Urgent)
|
|
54
|
+
* Stoneforge 2 (high) → Linear 2 (High)
|
|
55
|
+
* Stoneforge 3 (medium) → Linear 3 (Medium)
|
|
56
|
+
* Stoneforge 4 (low) → Linear 4 (Low)
|
|
57
|
+
* Stoneforge 5 (minimal) → Linear 0 (No priority)
|
|
58
|
+
*/
|
|
59
|
+
export function stoneforgePriorityToLinear(priority) {
|
|
60
|
+
switch (priority) {
|
|
61
|
+
case 1:
|
|
62
|
+
return 1; // critical → Urgent
|
|
63
|
+
case 2:
|
|
64
|
+
return 2; // high → High
|
|
65
|
+
case 3:
|
|
66
|
+
return 3; // medium → Medium
|
|
67
|
+
case 4:
|
|
68
|
+
return 4; // low → Low
|
|
69
|
+
case 5:
|
|
70
|
+
return 0; // minimal → No priority
|
|
71
|
+
default:
|
|
72
|
+
return 3; // fallback: Medium
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Maps Linear priority (0-4) to Stoneforge priority (1-5).
|
|
77
|
+
*
|
|
78
|
+
* Linear 1 (Urgent) → Stoneforge 1 (critical)
|
|
79
|
+
* Linear 2 (High) → Stoneforge 2 (high)
|
|
80
|
+
* Linear 3 (Medium) → Stoneforge 3 (medium)
|
|
81
|
+
* Linear 4 (Low) → Stoneforge 4 (low)
|
|
82
|
+
* Linear 0 (No priority) → Stoneforge 5 (minimal)
|
|
83
|
+
*/
|
|
84
|
+
export function linearPriorityToStoneforge(priority) {
|
|
85
|
+
switch (priority) {
|
|
86
|
+
case 1:
|
|
87
|
+
return 1; // Urgent → critical
|
|
88
|
+
case 2:
|
|
89
|
+
return 2; // High → high
|
|
90
|
+
case 3:
|
|
91
|
+
return 3; // Medium → medium
|
|
92
|
+
case 4:
|
|
93
|
+
return 4; // Low → low
|
|
94
|
+
case 0:
|
|
95
|
+
return 5; // No priority → minimal
|
|
96
|
+
default:
|
|
97
|
+
return 3; // fallback: medium
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Maps a Linear workflow state type to a Stoneforge TaskStatus.
|
|
102
|
+
*
|
|
103
|
+
* Pull direction:
|
|
104
|
+
* triage → backlog
|
|
105
|
+
* backlog → backlog
|
|
106
|
+
* unstarted → open
|
|
107
|
+
* started → in_progress
|
|
108
|
+
* completed → closed
|
|
109
|
+
* canceled → closed
|
|
110
|
+
*/
|
|
111
|
+
export function linearStateTypeToStatus(stateType) {
|
|
112
|
+
switch (stateType) {
|
|
113
|
+
case 'triage':
|
|
114
|
+
return { status: 'backlog' };
|
|
115
|
+
case 'backlog':
|
|
116
|
+
return { status: 'backlog' };
|
|
117
|
+
case 'unstarted':
|
|
118
|
+
return { status: 'open' };
|
|
119
|
+
case 'started':
|
|
120
|
+
return { status: 'in_progress' };
|
|
121
|
+
case 'completed':
|
|
122
|
+
return { status: 'closed' };
|
|
123
|
+
case 'canceled':
|
|
124
|
+
return { status: 'closed', closeReason: 'canceled' };
|
|
125
|
+
default:
|
|
126
|
+
return { status: 'open' };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Maps a Stoneforge TaskStatus to a Linear workflow state type.
|
|
131
|
+
*
|
|
132
|
+
* Push direction:
|
|
133
|
+
* open → unstarted
|
|
134
|
+
* in_progress → started
|
|
135
|
+
* review → started
|
|
136
|
+
* blocked → started (caller should add "blocked" label)
|
|
137
|
+
* deferred → backlog
|
|
138
|
+
* backlog → backlog
|
|
139
|
+
* closed → completed
|
|
140
|
+
* tombstone → completed (treat as done)
|
|
141
|
+
*/
|
|
142
|
+
export function statusToLinearStateType(status) {
|
|
143
|
+
switch (status) {
|
|
144
|
+
case 'open':
|
|
145
|
+
return 'unstarted';
|
|
146
|
+
case 'in_progress':
|
|
147
|
+
return 'started';
|
|
148
|
+
case 'review':
|
|
149
|
+
return 'started';
|
|
150
|
+
case 'blocked':
|
|
151
|
+
return 'started';
|
|
152
|
+
case 'deferred':
|
|
153
|
+
return 'backlog';
|
|
154
|
+
case 'backlog':
|
|
155
|
+
return 'backlog';
|
|
156
|
+
case 'closed':
|
|
157
|
+
return 'completed';
|
|
158
|
+
case 'tombstone':
|
|
159
|
+
return 'completed';
|
|
160
|
+
default:
|
|
161
|
+
return 'unstarted';
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Returns true if the given Stoneforge status should add a "blocked" label
|
|
166
|
+
* in Linear (since Linear has no native blocked state).
|
|
167
|
+
*/
|
|
168
|
+
export function shouldAddBlockedLabel(status) {
|
|
169
|
+
return status === 'blocked';
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Maps a Linear workflow state type to a sync label string (sf:status:*).
|
|
173
|
+
*
|
|
174
|
+
* The Linear adapter injects this label into ExternalTask.labels so the
|
|
175
|
+
* generic field mapping system (stateToStatus) can extract granular statuses
|
|
176
|
+
* without the sync engine needing to know about Linear-specific state types.
|
|
177
|
+
*
|
|
178
|
+
* Mapping:
|
|
179
|
+
* triage → sf:status:backlog
|
|
180
|
+
* backlog → sf:status:backlog
|
|
181
|
+
* unstarted → sf:status:open
|
|
182
|
+
* started → sf:status:in-progress
|
|
183
|
+
* completed → sf:status:closed
|
|
184
|
+
* canceled → sf:status:closed
|
|
185
|
+
*/
|
|
186
|
+
export function linearStateTypeToStatusLabel(stateType) {
|
|
187
|
+
switch (stateType) {
|
|
188
|
+
case 'triage':
|
|
189
|
+
return 'sf:status:backlog';
|
|
190
|
+
case 'backlog':
|
|
191
|
+
return 'sf:status:backlog';
|
|
192
|
+
case 'unstarted':
|
|
193
|
+
return 'sf:status:open';
|
|
194
|
+
case 'started':
|
|
195
|
+
return 'sf:status:in-progress';
|
|
196
|
+
case 'completed':
|
|
197
|
+
return 'sf:status:closed';
|
|
198
|
+
case 'canceled':
|
|
199
|
+
return 'sf:status:closed';
|
|
200
|
+
default:
|
|
201
|
+
return 'sf:status:open';
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// ============================================================================
|
|
205
|
+
// TaskFieldMapConfig (for TaskSyncAdapter.getFieldMapConfig())
|
|
206
|
+
// ============================================================================
|
|
207
|
+
/**
|
|
208
|
+
* Creates the Linear-specific TaskFieldMapConfig.
|
|
209
|
+
*
|
|
210
|
+
* This config describes the field mapping at the type level. The actual
|
|
211
|
+
* runtime mapping logic lives in the adapter and the priority/status
|
|
212
|
+
* functions above.
|
|
213
|
+
*/
|
|
214
|
+
export function createLinearFieldMapConfig() {
|
|
215
|
+
return {
|
|
216
|
+
provider: 'linear',
|
|
217
|
+
fields: [
|
|
218
|
+
{
|
|
219
|
+
localField: 'title',
|
|
220
|
+
externalField: 'title',
|
|
221
|
+
direction: 'bidirectional',
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
localField: 'descriptionRef',
|
|
225
|
+
externalField: 'description',
|
|
226
|
+
direction: 'bidirectional',
|
|
227
|
+
toExternal: 'hydrateDescription',
|
|
228
|
+
toLocal: 'createDescriptionDoc',
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
localField: 'status',
|
|
232
|
+
externalField: 'state',
|
|
233
|
+
direction: 'bidirectional',
|
|
234
|
+
toExternal: 'statusToLinearState',
|
|
235
|
+
toLocal: 'linearStateToStatus',
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
localField: 'priority',
|
|
239
|
+
externalField: 'priority',
|
|
240
|
+
direction: 'bidirectional',
|
|
241
|
+
toExternal: 'stoneforgePriorityToLinear',
|
|
242
|
+
toLocal: 'linearPriorityToStoneforge',
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
localField: 'tags',
|
|
246
|
+
externalField: 'labels',
|
|
247
|
+
direction: 'bidirectional',
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
localField: 'taskType',
|
|
251
|
+
externalField: 'labels',
|
|
252
|
+
direction: 'bidirectional',
|
|
253
|
+
toExternal: 'taskTypeToLabel',
|
|
254
|
+
toLocal: 'labelToTaskType',
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
localField: 'assignee',
|
|
258
|
+
externalField: 'assignee',
|
|
259
|
+
direction: 'bidirectional',
|
|
260
|
+
},
|
|
261
|
+
],
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
// ============================================================================
|
|
265
|
+
// TaskSyncFieldMapConfig (for shared adapter utilities)
|
|
266
|
+
// ============================================================================
|
|
267
|
+
/**
|
|
268
|
+
* Creates the Linear-specific TaskSyncFieldMapConfig used by the shared
|
|
269
|
+
* task-sync-adapter utilities (taskToExternalTask, externalTaskToTaskUpdates).
|
|
270
|
+
*
|
|
271
|
+
* Priority labels are emitted alongside Linear's native priority field for
|
|
272
|
+
* lossless round-tripping. This ensures the exact Stoneforge priority value
|
|
273
|
+
* is preserved (e.g., P5 "minimal" is distinct from Linear's "No priority").
|
|
274
|
+
*
|
|
275
|
+
* Status mapping uses adapter-injected sf:status:* labels. The Linear adapter
|
|
276
|
+
* injects these labels based on the workflow state type (e.g., started →
|
|
277
|
+
* sf:status:in-progress), allowing the generic stateToStatus function to
|
|
278
|
+
* extract granular statuses without coupling the sync engine to Linear.
|
|
279
|
+
*/
|
|
280
|
+
export function createLinearSyncFieldMapConfig() {
|
|
281
|
+
return {
|
|
282
|
+
// Priority labels for lossless round-tripping. These are synced as Linear
|
|
283
|
+
// labels alongside the native priority field, so the exact Stoneforge
|
|
284
|
+
// priority value is preserved on round-trip.
|
|
285
|
+
priorityLabels: {
|
|
286
|
+
1: 'priority:critical',
|
|
287
|
+
2: 'priority:high',
|
|
288
|
+
3: 'priority:medium',
|
|
289
|
+
4: 'priority:low',
|
|
290
|
+
5: 'priority:minimal',
|
|
291
|
+
},
|
|
292
|
+
taskTypeLabels: {
|
|
293
|
+
bug: 'type:bug',
|
|
294
|
+
feature: 'type:feature',
|
|
295
|
+
task: 'type:task',
|
|
296
|
+
chore: 'type:chore',
|
|
297
|
+
},
|
|
298
|
+
// Status labels for reading adapter-injected sf:status:* labels on pull.
|
|
299
|
+
// The Linear adapter injects these labels based on workflow state type,
|
|
300
|
+
// so parseExternalLabels() and stateToStatus() can extract granular statuses.
|
|
301
|
+
statusLabels: LINEAR_STATUS_LABELS,
|
|
302
|
+
syncLabelPrefix: 'sf:',
|
|
303
|
+
statusToState: (status) => {
|
|
304
|
+
// For the shared adapter utility, we still need open/closed.
|
|
305
|
+
// The actual state type mapping is handled by the adapter.
|
|
306
|
+
switch (status) {
|
|
307
|
+
case 'closed':
|
|
308
|
+
case 'tombstone':
|
|
309
|
+
return 'closed';
|
|
310
|
+
default:
|
|
311
|
+
return 'open';
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
stateToStatus: (state, labels) => {
|
|
315
|
+
// Check for adapter-injected sf:status:* labels first.
|
|
316
|
+
// The Linear adapter injects these based on workflow state type
|
|
317
|
+
// (e.g., started → sf:status:in-progress), giving us granular status
|
|
318
|
+
// without coupling the sync engine to Linear-specific state types.
|
|
319
|
+
const statusByLabel = new Map();
|
|
320
|
+
for (const [status, label] of Object.entries(LINEAR_STATUS_LABELS)) {
|
|
321
|
+
statusByLabel.set(label, status);
|
|
322
|
+
}
|
|
323
|
+
const prefix = 'sf:';
|
|
324
|
+
for (const label of labels) {
|
|
325
|
+
if (label.startsWith(prefix)) {
|
|
326
|
+
const value = label.slice(prefix.length);
|
|
327
|
+
const matchedStatus = statusByLabel.get(value);
|
|
328
|
+
if (matchedStatus !== undefined) {
|
|
329
|
+
return matchedStatus;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
// Fallback: basic open/closed mapping when no status label is present
|
|
334
|
+
return state === 'closed' ? 'closed' : 'open';
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
//# sourceMappingURL=linear-field-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-field-map.js","sourceRoot":"","sources":["../../../../src/external-sync/providers/linear/linear-field-map.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linear External Provider
|
|
3
|
+
*
|
|
4
|
+
* Implements the ExternalProvider interface for Linear.
|
|
5
|
+
* Handles connection validation and provides access to the LinearTaskAdapter.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - Provider handles auth configuration and connection testing
|
|
9
|
+
* - Task adapter handles issue CRUD operations and field mapping
|
|
10
|
+
* - API client handles GraphQL requests and rate limiting
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const provider = createLinearProvider({ apiKey: 'lin_api_...' });
|
|
15
|
+
* const registry = createProviderRegistry();
|
|
16
|
+
* registry.register(provider);
|
|
17
|
+
*
|
|
18
|
+
* // Test connection
|
|
19
|
+
* const connected = await provider.testConnection({ provider: 'linear', token: 'lin_api_...' });
|
|
20
|
+
*
|
|
21
|
+
* // Get task adapter
|
|
22
|
+
* const adapter = provider.getTaskAdapter();
|
|
23
|
+
* const issues = await adapter.listIssuesSince('ENG', '2024-01-01T00:00:00Z');
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
import type { ExternalProvider } from '@stoneforge/core';
|
|
27
|
+
/**
|
|
28
|
+
* Options for creating a Linear provider.
|
|
29
|
+
*/
|
|
30
|
+
export interface CreateLinearProviderOptions {
|
|
31
|
+
/** Linear API key for authentication */
|
|
32
|
+
apiKey: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a Linear ExternalProvider.
|
|
36
|
+
*
|
|
37
|
+
* The provider is fully configured with the given API key and ready
|
|
38
|
+
* for registration in the provider registry.
|
|
39
|
+
*
|
|
40
|
+
* @param options - Configuration including the API key
|
|
41
|
+
* @returns A configured Linear ExternalProvider
|
|
42
|
+
*/
|
|
43
|
+
export declare function createLinearProvider(options: CreateLinearProviderOptions): ExternalProvider;
|
|
44
|
+
/**
|
|
45
|
+
* Create a placeholder Linear provider for registry registration.
|
|
46
|
+
*
|
|
47
|
+
* Similar to the GitHub placeholder — registers the provider shape so the
|
|
48
|
+
* registry knows Linear is available. Connection testing always returns false.
|
|
49
|
+
* The actual provider is created with createLinearProvider() when configured.
|
|
50
|
+
*/
|
|
51
|
+
export declare function createLinearPlaceholderProvider(): ExternalProvider;
|
|
52
|
+
//# sourceMappingURL=linear-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-provider.d.ts","sourceRoot":"","sources":["../../../../src/external-sync/providers/linear/linear-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAIjB,MAAM,kBAAkB,CAAC;AAsE1B;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,gBAAgB,CAG3F;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,IAAI,gBAAgB,CAElE"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linear External Provider
|
|
3
|
+
*
|
|
4
|
+
* Implements the ExternalProvider interface for Linear.
|
|
5
|
+
* Handles connection validation and provides access to the LinearTaskAdapter.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - Provider handles auth configuration and connection testing
|
|
9
|
+
* - Task adapter handles issue CRUD operations and field mapping
|
|
10
|
+
* - API client handles GraphQL requests and rate limiting
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const provider = createLinearProvider({ apiKey: 'lin_api_...' });
|
|
15
|
+
* const registry = createProviderRegistry();
|
|
16
|
+
* registry.register(provider);
|
|
17
|
+
*
|
|
18
|
+
* // Test connection
|
|
19
|
+
* const connected = await provider.testConnection({ provider: 'linear', token: 'lin_api_...' });
|
|
20
|
+
*
|
|
21
|
+
* // Get task adapter
|
|
22
|
+
* const adapter = provider.getTaskAdapter();
|
|
23
|
+
* const issues = await adapter.listIssuesSince('ENG', '2024-01-01T00:00:00Z');
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
import { LinearApiClient } from './linear-api.js';
|
|
27
|
+
import { LinearTaskAdapter } from './linear-task-adapter.js';
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// LinearProvider
|
|
30
|
+
// ============================================================================
|
|
31
|
+
/**
|
|
32
|
+
* ExternalProvider implementation for Linear.
|
|
33
|
+
*
|
|
34
|
+
* Supports task sync only. Connection testing uses the getViewer() API call
|
|
35
|
+
* to verify the API key is valid.
|
|
36
|
+
*/
|
|
37
|
+
class LinearProvider {
|
|
38
|
+
name = 'linear';
|
|
39
|
+
displayName = 'Linear';
|
|
40
|
+
supportedAdapters = ['task'];
|
|
41
|
+
taskAdapter;
|
|
42
|
+
constructor(api) {
|
|
43
|
+
this.taskAdapter = new LinearTaskAdapter(api);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Test whether the connection to Linear is valid.
|
|
47
|
+
*
|
|
48
|
+
* Calls getViewer() to verify the API key works. The config parameter
|
|
49
|
+
* provides the token for providers that are configured dynamically,
|
|
50
|
+
* but this provider was constructed with a client already.
|
|
51
|
+
*
|
|
52
|
+
* @param _config - Provider configuration (token is already set in client)
|
|
53
|
+
* @returns true if the connection is valid, false otherwise
|
|
54
|
+
*/
|
|
55
|
+
async testConnection(_config) {
|
|
56
|
+
try {
|
|
57
|
+
// Use a temporary client if config provides a different token,
|
|
58
|
+
// or fall back to testing the existing adapter's connection
|
|
59
|
+
const viewer = await this.getApiClient().getViewer();
|
|
60
|
+
return viewer !== null && viewer !== undefined;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Returns the task sync adapter.
|
|
68
|
+
*/
|
|
69
|
+
getTaskAdapter() {
|
|
70
|
+
return this.taskAdapter;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Access the underlying API client (used internally for connection testing).
|
|
74
|
+
*/
|
|
75
|
+
getApiClient() {
|
|
76
|
+
// The API client is encapsulated in the task adapter.
|
|
77
|
+
// For connection testing, we construct a minimal client inline.
|
|
78
|
+
// This is a workaround; in the full implementation, the provider
|
|
79
|
+
// would hold a direct reference to the client.
|
|
80
|
+
return this.taskAdapter.api;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Create a Linear ExternalProvider.
|
|
85
|
+
*
|
|
86
|
+
* The provider is fully configured with the given API key and ready
|
|
87
|
+
* for registration in the provider registry.
|
|
88
|
+
*
|
|
89
|
+
* @param options - Configuration including the API key
|
|
90
|
+
* @returns A configured Linear ExternalProvider
|
|
91
|
+
*/
|
|
92
|
+
export function createLinearProvider(options) {
|
|
93
|
+
const api = new LinearApiClient({ apiKey: options.apiKey });
|
|
94
|
+
return new LinearProvider(api);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Create a placeholder Linear provider for registry registration.
|
|
98
|
+
*
|
|
99
|
+
* Similar to the GitHub placeholder — registers the provider shape so the
|
|
100
|
+
* registry knows Linear is available. Connection testing always returns false.
|
|
101
|
+
* The actual provider is created with createLinearProvider() when configured.
|
|
102
|
+
*/
|
|
103
|
+
export function createLinearPlaceholderProvider() {
|
|
104
|
+
return new LinearPlaceholderProvider();
|
|
105
|
+
}
|
|
106
|
+
// ============================================================================
|
|
107
|
+
// Placeholder Provider (for default registry)
|
|
108
|
+
// ============================================================================
|
|
109
|
+
const PLACEHOLDER_MESSAGE = 'Linear task sync adapter is not yet configured. Set a Linear API key to enable sync.';
|
|
110
|
+
/**
|
|
111
|
+
* Placeholder TaskSyncAdapter for Linear.
|
|
112
|
+
* All methods throw to indicate they are not yet configured.
|
|
113
|
+
*/
|
|
114
|
+
class LinearPlaceholderTaskAdapter {
|
|
115
|
+
async getIssue(_project, _externalId) {
|
|
116
|
+
throw new Error(PLACEHOLDER_MESSAGE);
|
|
117
|
+
}
|
|
118
|
+
async listIssuesSince(_project, _since) {
|
|
119
|
+
throw new Error(PLACEHOLDER_MESSAGE);
|
|
120
|
+
}
|
|
121
|
+
async createIssue(_project, _issue) {
|
|
122
|
+
throw new Error(PLACEHOLDER_MESSAGE);
|
|
123
|
+
}
|
|
124
|
+
async updateIssue(_project, _externalId, _updates) {
|
|
125
|
+
throw new Error(PLACEHOLDER_MESSAGE);
|
|
126
|
+
}
|
|
127
|
+
getFieldMapConfig() {
|
|
128
|
+
// Return the field map config even in placeholder mode
|
|
129
|
+
// so the system can introspect the mapping shape
|
|
130
|
+
return {
|
|
131
|
+
provider: 'linear',
|
|
132
|
+
fields: [
|
|
133
|
+
{
|
|
134
|
+
localField: 'title',
|
|
135
|
+
externalField: 'title',
|
|
136
|
+
direction: 'bidirectional',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
localField: 'status',
|
|
140
|
+
externalField: 'state',
|
|
141
|
+
direction: 'bidirectional',
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
localField: 'priority',
|
|
145
|
+
externalField: 'priority',
|
|
146
|
+
direction: 'bidirectional',
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Placeholder Linear ExternalProvider.
|
|
154
|
+
* Declares Linear as a known provider that supports task sync.
|
|
155
|
+
* Connection testing always returns false (not configured).
|
|
156
|
+
*/
|
|
157
|
+
class LinearPlaceholderProvider {
|
|
158
|
+
name = 'linear';
|
|
159
|
+
displayName = 'Linear';
|
|
160
|
+
supportedAdapters = ['task'];
|
|
161
|
+
taskAdapter = new LinearPlaceholderTaskAdapter();
|
|
162
|
+
async testConnection(_config) {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
getTaskAdapter() {
|
|
166
|
+
return this.taskAdapter;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=linear-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-provider.js","sourceRoot":"","sources":["../../../../src/external-sync/providers/linear/linear-provider.ts"],"names":[],"mappings":"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"}
|