@harness-engineering/core 0.20.0 → 0.21.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/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +47 -31
- package/dist/index.mjs +47 -31
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -6478,7 +6478,7 @@ declare class GitHubIssuesSyncAdapter implements TrackerSyncAdapter {
|
|
|
6478
6478
|
* Mutates `roadmap` in-place (stores new externalIds).
|
|
6479
6479
|
* Never throws -- errors collected per-feature.
|
|
6480
6480
|
*/
|
|
6481
|
-
declare function syncToExternal(roadmap: Roadmap, adapter: TrackerSyncAdapter,
|
|
6481
|
+
declare function syncToExternal(roadmap: Roadmap, adapter: TrackerSyncAdapter, config: TrackerSyncConfig, prefetchedTickets?: ExternalTicketState[]): Promise<SyncResult>;
|
|
6482
6482
|
/**
|
|
6483
6483
|
* Pull execution fields (assignee, status) from external service.
|
|
6484
6484
|
* - External assignee wins over local assignee
|
|
@@ -6487,7 +6487,7 @@ declare function syncToExternal(roadmap: Roadmap, adapter: TrackerSyncAdapter, _
|
|
|
6487
6487
|
* Mutates `roadmap` in-place.
|
|
6488
6488
|
* Never throws -- errors collected per-feature.
|
|
6489
6489
|
*/
|
|
6490
|
-
declare function syncFromExternal(roadmap: Roadmap, adapter: TrackerSyncAdapter, config: TrackerSyncConfig, options?: ExternalSyncOptions): Promise<SyncResult>;
|
|
6490
|
+
declare function syncFromExternal(roadmap: Roadmap, adapter: TrackerSyncAdapter, config: TrackerSyncConfig, options?: ExternalSyncOptions, prefetchedTickets?: ExternalTicketState[]): Promise<SyncResult>;
|
|
6491
6491
|
/**
|
|
6492
6492
|
* Full bidirectional sync: read roadmap, push, pull, write back.
|
|
6493
6493
|
* Serialized by in-process mutex.
|
package/dist/index.d.ts
CHANGED
|
@@ -6478,7 +6478,7 @@ declare class GitHubIssuesSyncAdapter implements TrackerSyncAdapter {
|
|
|
6478
6478
|
* Mutates `roadmap` in-place (stores new externalIds).
|
|
6479
6479
|
* Never throws -- errors collected per-feature.
|
|
6480
6480
|
*/
|
|
6481
|
-
declare function syncToExternal(roadmap: Roadmap, adapter: TrackerSyncAdapter,
|
|
6481
|
+
declare function syncToExternal(roadmap: Roadmap, adapter: TrackerSyncAdapter, config: TrackerSyncConfig, prefetchedTickets?: ExternalTicketState[]): Promise<SyncResult>;
|
|
6482
6482
|
/**
|
|
6483
6483
|
* Pull execution fields (assignee, status) from external service.
|
|
6484
6484
|
* - External assignee wins over local assignee
|
|
@@ -6487,7 +6487,7 @@ declare function syncToExternal(roadmap: Roadmap, adapter: TrackerSyncAdapter, _
|
|
|
6487
6487
|
* Mutates `roadmap` in-place.
|
|
6488
6488
|
* Never throws -- errors collected per-feature.
|
|
6489
6489
|
*/
|
|
6490
|
-
declare function syncFromExternal(roadmap: Roadmap, adapter: TrackerSyncAdapter, config: TrackerSyncConfig, options?: ExternalSyncOptions): Promise<SyncResult>;
|
|
6490
|
+
declare function syncFromExternal(roadmap: Roadmap, adapter: TrackerSyncAdapter, config: TrackerSyncConfig, options?: ExternalSyncOptions, prefetchedTickets?: ExternalTicketState[]): Promise<SyncResult>;
|
|
6491
6491
|
/**
|
|
6492
6492
|
* Full bidirectional sync: read roadmap, push, pull, write back.
|
|
6493
6493
|
* Serialized by in-process mutex.
|
package/dist/index.js
CHANGED
|
@@ -13767,6 +13767,7 @@ var GitHubIssuesSyncAdapter = class {
|
|
|
13767
13767
|
const data = await response.json();
|
|
13768
13768
|
return (0, import_types25.Ok)({
|
|
13769
13769
|
externalId,
|
|
13770
|
+
title: data.title,
|
|
13770
13771
|
status: data.state,
|
|
13771
13772
|
labels: data.labels.map((l) => l.name),
|
|
13772
13773
|
assignee: data.assignee ? `@${data.assignee.login}` : null
|
|
@@ -13801,6 +13802,7 @@ var GitHubIssuesSyncAdapter = class {
|
|
|
13801
13802
|
for (const issue of issues) {
|
|
13802
13803
|
tickets.push({
|
|
13803
13804
|
externalId: buildExternalId(this.owner, this.repo, issue.number),
|
|
13805
|
+
title: issue.title,
|
|
13804
13806
|
status: issue.state,
|
|
13805
13807
|
labels: issue.labels.map((l) => l.name),
|
|
13806
13808
|
assignee: issue.assignee ? `@${issue.assignee.login}` : null
|
|
@@ -13845,43 +13847,49 @@ var fs22 = __toESM(require("fs"));
|
|
|
13845
13847
|
function emptySyncResult() {
|
|
13846
13848
|
return { created: [], updated: [], assignmentChanges: [], errors: [] };
|
|
13847
13849
|
}
|
|
13848
|
-
async function syncToExternal(roadmap, adapter,
|
|
13850
|
+
async function syncToExternal(roadmap, adapter, config, prefetchedTickets) {
|
|
13849
13851
|
const result = emptySyncResult();
|
|
13850
|
-
|
|
13851
|
-
const
|
|
13852
|
-
if (
|
|
13853
|
-
|
|
13852
|
+
const existingByTitle = /* @__PURE__ */ new Map();
|
|
13853
|
+
const configLabels = new Set((config.labels ?? []).map((l) => l.toLowerCase()));
|
|
13854
|
+
if (prefetchedTickets) {
|
|
13855
|
+
for (const ticket of prefetchedTickets) {
|
|
13856
|
+
const hasConfigLabels = configLabels.size === 0 || ticket.labels.some((l) => configLabels.has(l.toLowerCase()));
|
|
13857
|
+
if (!hasConfigLabels) continue;
|
|
13858
|
+
const key = ticket.title.toLowerCase();
|
|
13859
|
+
const prev = existingByTitle.get(key);
|
|
13860
|
+
if (!prev || prev.status === "closed" && ticket.status === "open") {
|
|
13861
|
+
existingByTitle.set(key, ticket);
|
|
13862
|
+
}
|
|
13863
|
+
}
|
|
13854
13864
|
}
|
|
13855
13865
|
for (const milestone of roadmap.milestones) {
|
|
13856
13866
|
for (const feature of milestone.features) {
|
|
13857
|
-
if (!feature.assignee && defaultAssignee) {
|
|
13858
|
-
feature.assignee = defaultAssignee;
|
|
13859
|
-
}
|
|
13860
13867
|
if (!feature.externalId) {
|
|
13861
|
-
const
|
|
13862
|
-
if (
|
|
13863
|
-
feature.externalId =
|
|
13864
|
-
result.created.push(createResult.value);
|
|
13868
|
+
const existing = existingByTitle.get(feature.name.toLowerCase());
|
|
13869
|
+
if (existing) {
|
|
13870
|
+
feature.externalId = existing.externalId;
|
|
13865
13871
|
} else {
|
|
13866
|
-
|
|
13872
|
+
const createResult = await adapter.createTicket(feature, milestone.name);
|
|
13873
|
+
if (createResult.ok) {
|
|
13874
|
+
feature.externalId = createResult.value.externalId;
|
|
13875
|
+
result.created.push(createResult.value);
|
|
13876
|
+
} else {
|
|
13877
|
+
result.errors.push({ featureOrId: feature.name, error: createResult.error });
|
|
13878
|
+
}
|
|
13879
|
+
continue;
|
|
13867
13880
|
}
|
|
13881
|
+
}
|
|
13882
|
+
const updateResult = await adapter.updateTicket(feature.externalId, feature, milestone.name);
|
|
13883
|
+
if (updateResult.ok) {
|
|
13884
|
+
result.updated.push(feature.externalId);
|
|
13868
13885
|
} else {
|
|
13869
|
-
|
|
13870
|
-
feature.externalId,
|
|
13871
|
-
feature,
|
|
13872
|
-
milestone.name
|
|
13873
|
-
);
|
|
13874
|
-
if (updateResult.ok) {
|
|
13875
|
-
result.updated.push(feature.externalId);
|
|
13876
|
-
} else {
|
|
13877
|
-
result.errors.push({ featureOrId: feature.externalId, error: updateResult.error });
|
|
13878
|
-
}
|
|
13886
|
+
result.errors.push({ featureOrId: feature.externalId, error: updateResult.error });
|
|
13879
13887
|
}
|
|
13880
13888
|
}
|
|
13881
13889
|
}
|
|
13882
13890
|
return result;
|
|
13883
13891
|
}
|
|
13884
|
-
async function syncFromExternal(roadmap, adapter, config, options) {
|
|
13892
|
+
async function syncFromExternal(roadmap, adapter, config, options, prefetchedTickets) {
|
|
13885
13893
|
const result = emptySyncResult();
|
|
13886
13894
|
const forceSync = options?.forceSync ?? false;
|
|
13887
13895
|
const featureByExternalId = /* @__PURE__ */ new Map();
|
|
@@ -13893,12 +13901,18 @@ async function syncFromExternal(roadmap, adapter, config, options) {
|
|
|
13893
13901
|
}
|
|
13894
13902
|
}
|
|
13895
13903
|
if (featureByExternalId.size === 0) return result;
|
|
13896
|
-
|
|
13897
|
-
if (
|
|
13898
|
-
|
|
13899
|
-
|
|
13904
|
+
let tickets;
|
|
13905
|
+
if (prefetchedTickets) {
|
|
13906
|
+
tickets = prefetchedTickets;
|
|
13907
|
+
} else {
|
|
13908
|
+
const fetchResult = await adapter.fetchAllTickets();
|
|
13909
|
+
if (!fetchResult.ok) {
|
|
13910
|
+
result.errors.push({ featureOrId: "*", error: fetchResult.error });
|
|
13911
|
+
return result;
|
|
13912
|
+
}
|
|
13913
|
+
tickets = fetchResult.value;
|
|
13900
13914
|
}
|
|
13901
|
-
for (const ticketState of
|
|
13915
|
+
for (const ticketState of tickets) {
|
|
13902
13916
|
const feature = featureByExternalId.get(ticketState.externalId);
|
|
13903
13917
|
if (!feature) continue;
|
|
13904
13918
|
if (ticketState.assignee !== feature.assignee) {
|
|
@@ -13938,8 +13952,10 @@ async function fullSync(roadmapPath, adapter, config, options) {
|
|
|
13938
13952
|
};
|
|
13939
13953
|
}
|
|
13940
13954
|
const roadmap = parseResult.value;
|
|
13941
|
-
const
|
|
13942
|
-
const
|
|
13955
|
+
const fetchResult = await adapter.fetchAllTickets();
|
|
13956
|
+
const tickets = fetchResult.ok ? fetchResult.value : void 0;
|
|
13957
|
+
const pushResult = await syncToExternal(roadmap, adapter, config, tickets);
|
|
13958
|
+
const pullResult = await syncFromExternal(roadmap, adapter, config, options, tickets);
|
|
13943
13959
|
fs22.writeFileSync(roadmapPath, serializeRoadmap(roadmap), "utf-8");
|
|
13944
13960
|
return {
|
|
13945
13961
|
created: pushResult.created,
|
package/dist/index.mjs
CHANGED
|
@@ -11632,6 +11632,7 @@ var GitHubIssuesSyncAdapter = class {
|
|
|
11632
11632
|
const data = await response.json();
|
|
11633
11633
|
return Ok4({
|
|
11634
11634
|
externalId,
|
|
11635
|
+
title: data.title,
|
|
11635
11636
|
status: data.state,
|
|
11636
11637
|
labels: data.labels.map((l) => l.name),
|
|
11637
11638
|
assignee: data.assignee ? `@${data.assignee.login}` : null
|
|
@@ -11666,6 +11667,7 @@ var GitHubIssuesSyncAdapter = class {
|
|
|
11666
11667
|
for (const issue of issues) {
|
|
11667
11668
|
tickets.push({
|
|
11668
11669
|
externalId: buildExternalId(this.owner, this.repo, issue.number),
|
|
11670
|
+
title: issue.title,
|
|
11669
11671
|
status: issue.state,
|
|
11670
11672
|
labels: issue.labels.map((l) => l.name),
|
|
11671
11673
|
assignee: issue.assignee ? `@${issue.assignee.login}` : null
|
|
@@ -11710,43 +11712,49 @@ import * as fs22 from "fs";
|
|
|
11710
11712
|
function emptySyncResult() {
|
|
11711
11713
|
return { created: [], updated: [], assignmentChanges: [], errors: [] };
|
|
11712
11714
|
}
|
|
11713
|
-
async function syncToExternal(roadmap, adapter,
|
|
11715
|
+
async function syncToExternal(roadmap, adapter, config, prefetchedTickets) {
|
|
11714
11716
|
const result = emptySyncResult();
|
|
11715
|
-
|
|
11716
|
-
const
|
|
11717
|
-
if (
|
|
11718
|
-
|
|
11717
|
+
const existingByTitle = /* @__PURE__ */ new Map();
|
|
11718
|
+
const configLabels = new Set((config.labels ?? []).map((l) => l.toLowerCase()));
|
|
11719
|
+
if (prefetchedTickets) {
|
|
11720
|
+
for (const ticket of prefetchedTickets) {
|
|
11721
|
+
const hasConfigLabels = configLabels.size === 0 || ticket.labels.some((l) => configLabels.has(l.toLowerCase()));
|
|
11722
|
+
if (!hasConfigLabels) continue;
|
|
11723
|
+
const key = ticket.title.toLowerCase();
|
|
11724
|
+
const prev = existingByTitle.get(key);
|
|
11725
|
+
if (!prev || prev.status === "closed" && ticket.status === "open") {
|
|
11726
|
+
existingByTitle.set(key, ticket);
|
|
11727
|
+
}
|
|
11728
|
+
}
|
|
11719
11729
|
}
|
|
11720
11730
|
for (const milestone of roadmap.milestones) {
|
|
11721
11731
|
for (const feature of milestone.features) {
|
|
11722
|
-
if (!feature.assignee && defaultAssignee) {
|
|
11723
|
-
feature.assignee = defaultAssignee;
|
|
11724
|
-
}
|
|
11725
11732
|
if (!feature.externalId) {
|
|
11726
|
-
const
|
|
11727
|
-
if (
|
|
11728
|
-
feature.externalId =
|
|
11729
|
-
result.created.push(createResult.value);
|
|
11733
|
+
const existing = existingByTitle.get(feature.name.toLowerCase());
|
|
11734
|
+
if (existing) {
|
|
11735
|
+
feature.externalId = existing.externalId;
|
|
11730
11736
|
} else {
|
|
11731
|
-
|
|
11737
|
+
const createResult = await adapter.createTicket(feature, milestone.name);
|
|
11738
|
+
if (createResult.ok) {
|
|
11739
|
+
feature.externalId = createResult.value.externalId;
|
|
11740
|
+
result.created.push(createResult.value);
|
|
11741
|
+
} else {
|
|
11742
|
+
result.errors.push({ featureOrId: feature.name, error: createResult.error });
|
|
11743
|
+
}
|
|
11744
|
+
continue;
|
|
11732
11745
|
}
|
|
11746
|
+
}
|
|
11747
|
+
const updateResult = await adapter.updateTicket(feature.externalId, feature, milestone.name);
|
|
11748
|
+
if (updateResult.ok) {
|
|
11749
|
+
result.updated.push(feature.externalId);
|
|
11733
11750
|
} else {
|
|
11734
|
-
|
|
11735
|
-
feature.externalId,
|
|
11736
|
-
feature,
|
|
11737
|
-
milestone.name
|
|
11738
|
-
);
|
|
11739
|
-
if (updateResult.ok) {
|
|
11740
|
-
result.updated.push(feature.externalId);
|
|
11741
|
-
} else {
|
|
11742
|
-
result.errors.push({ featureOrId: feature.externalId, error: updateResult.error });
|
|
11743
|
-
}
|
|
11751
|
+
result.errors.push({ featureOrId: feature.externalId, error: updateResult.error });
|
|
11744
11752
|
}
|
|
11745
11753
|
}
|
|
11746
11754
|
}
|
|
11747
11755
|
return result;
|
|
11748
11756
|
}
|
|
11749
|
-
async function syncFromExternal(roadmap, adapter, config, options) {
|
|
11757
|
+
async function syncFromExternal(roadmap, adapter, config, options, prefetchedTickets) {
|
|
11750
11758
|
const result = emptySyncResult();
|
|
11751
11759
|
const forceSync = options?.forceSync ?? false;
|
|
11752
11760
|
const featureByExternalId = /* @__PURE__ */ new Map();
|
|
@@ -11758,12 +11766,18 @@ async function syncFromExternal(roadmap, adapter, config, options) {
|
|
|
11758
11766
|
}
|
|
11759
11767
|
}
|
|
11760
11768
|
if (featureByExternalId.size === 0) return result;
|
|
11761
|
-
|
|
11762
|
-
if (
|
|
11763
|
-
|
|
11764
|
-
|
|
11769
|
+
let tickets;
|
|
11770
|
+
if (prefetchedTickets) {
|
|
11771
|
+
tickets = prefetchedTickets;
|
|
11772
|
+
} else {
|
|
11773
|
+
const fetchResult = await adapter.fetchAllTickets();
|
|
11774
|
+
if (!fetchResult.ok) {
|
|
11775
|
+
result.errors.push({ featureOrId: "*", error: fetchResult.error });
|
|
11776
|
+
return result;
|
|
11777
|
+
}
|
|
11778
|
+
tickets = fetchResult.value;
|
|
11765
11779
|
}
|
|
11766
|
-
for (const ticketState of
|
|
11780
|
+
for (const ticketState of tickets) {
|
|
11767
11781
|
const feature = featureByExternalId.get(ticketState.externalId);
|
|
11768
11782
|
if (!feature) continue;
|
|
11769
11783
|
if (ticketState.assignee !== feature.assignee) {
|
|
@@ -11803,8 +11817,10 @@ async function fullSync(roadmapPath, adapter, config, options) {
|
|
|
11803
11817
|
};
|
|
11804
11818
|
}
|
|
11805
11819
|
const roadmap = parseResult.value;
|
|
11806
|
-
const
|
|
11807
|
-
const
|
|
11820
|
+
const fetchResult = await adapter.fetchAllTickets();
|
|
11821
|
+
const tickets = fetchResult.ok ? fetchResult.value : void 0;
|
|
11822
|
+
const pushResult = await syncToExternal(roadmap, adapter, config, tickets);
|
|
11823
|
+
const pullResult = await syncFromExternal(roadmap, adapter, config, options, tickets);
|
|
11808
11824
|
fs22.writeFileSync(roadmapPath, serializeRoadmap(roadmap), "utf-8");
|
|
11809
11825
|
return {
|
|
11810
11826
|
created: pushResult.created,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@harness-engineering/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Core library for Harness Engineering toolkit",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"web-tree-sitter": "^0.24.7",
|
|
51
51
|
"zod": "^3.25.76",
|
|
52
52
|
"@harness-engineering/graph": "0.4.0",
|
|
53
|
-
"@harness-engineering/types": "0.
|
|
53
|
+
"@harness-engineering/types": "0.9.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/ejs": "^3.1.5",
|