@ship-cli/core 0.1.11 → 0.1.12

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 (2) hide show
  1. package/dist/bin.js +148 -40
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -188905,6 +188905,28 @@ var restackCommand = make58(
188905
188905
  return;
188906
188906
  }
188907
188907
  const { vcs } = vcsCheck;
188908
+ const defaultBranch = yield* getDefaultBranch();
188909
+ if (!json2) {
188910
+ yield* log3("Fetching from remote...");
188911
+ }
188912
+ const fetchResult = yield* vcs.fetch().pipe(
188913
+ map17(() => ({ success: true })),
188914
+ catchAll2((e2) => succeed7({ success: false, error: formatEffectError(e2) }))
188915
+ );
188916
+ if (!fetchResult.success) {
188917
+ const output2 = {
188918
+ fetched: false,
188919
+ restacked: false,
188920
+ pushed: false,
188921
+ error: fetchResult.error
188922
+ };
188923
+ if (json2) {
188924
+ yield* log3(JSON.stringify(output2, null, 2));
188925
+ } else {
188926
+ yield* outputError(`Fetch failed: ${fetchResult.error}`, json2);
188927
+ }
188928
+ return;
188929
+ }
188908
188930
  const stack2 = yield* vcs.getStack().pipe(
188909
188931
  catchAll2((e2) => {
188910
188932
  return succeed7({ error: formatEffectError(e2), changes: [] });
@@ -188921,11 +188943,15 @@ var restackCommand = make58(
188921
188943
  catchAll2(() => succeed7({ success: false }))
188922
188944
  );
188923
188945
  const output2 = trunkResult2.success ? {
188946
+ fetched: true,
188924
188947
  restacked: false,
188948
+ pushed: false,
188925
188949
  stackSize: 0,
188926
188950
  trunkChangeId: trunkResult2.trunk.shortChangeId
188927
188951
  } : {
188952
+ fetched: true,
188928
188953
  restacked: false,
188954
+ pushed: false,
188929
188955
  stackSize: 0
188930
188956
  };
188931
188957
  if (json2) {
@@ -188938,8 +188964,10 @@ var restackCommand = make58(
188938
188964
  }
188939
188965
  return;
188940
188966
  }
188967
+ if (!json2) {
188968
+ yield* log3("Rebasing stack onto trunk...");
188969
+ }
188941
188970
  const firstInStack = changes2[changes2.length - 1];
188942
- const defaultBranch = yield* getDefaultBranch();
188943
188971
  const rebaseResult = yield* vcs.rebase(firstInStack.id, defaultBranch).pipe(
188944
188972
  map17(() => ({ success: true, conflicted: false })),
188945
188973
  catchTag2(
@@ -188952,7 +188980,9 @@ var restackCommand = make58(
188952
188980
  );
188953
188981
  if (!rebaseResult.success) {
188954
188982
  const output2 = {
188983
+ fetched: true,
188955
188984
  restacked: false,
188985
+ pushed: false,
188956
188986
  error: rebaseResult.error
188957
188987
  };
188958
188988
  if (json2) {
@@ -188962,43 +188992,96 @@ var restackCommand = make58(
188962
188992
  }
188963
188993
  return;
188964
188994
  }
188995
+ if (rebaseResult.conflicted) {
188996
+ const stackAfter2 = yield* vcs.getStack().pipe(
188997
+ map17((s) => s.length),
188998
+ catchAll2(() => succeed7(changes2.length))
188999
+ );
189000
+ const trunkResult2 = yield* vcs.getTrunkInfo().pipe(
189001
+ map17((trunk) => ({ success: true, trunk })),
189002
+ catchAll2(() => succeed7({ success: false }))
189003
+ );
189004
+ const output2 = {
189005
+ fetched: true,
189006
+ restacked: true,
189007
+ pushed: false,
189008
+ stackSize: stackAfter2,
189009
+ trunkChangeId: trunkResult2.success ? trunkResult2.trunk.shortChangeId : void 0,
189010
+ conflicted: true
189011
+ };
189012
+ if (json2) {
189013
+ yield* log3(JSON.stringify(output2, null, 2));
189014
+ } else {
189015
+ yield* log3("Restack completed with conflicts!");
189016
+ yield* log3(` Fetched: yes`);
189017
+ yield* log3(` Rebased: yes (with conflicts)`);
189018
+ if (trunkResult2.success) {
189019
+ yield* log3(` Trunk: ${trunkResult2.trunk.shortChangeId.slice(0, 12)}`);
189020
+ }
189021
+ yield* log3(` Stack: ${stackAfter2} change(s)`);
189022
+ yield* log3(` Pushed: no (conflicts must be resolved first)`);
189023
+ yield* log3("");
189024
+ yield* log3("Resolve conflicts with 'jj status' and edit the conflicted files.");
189025
+ yield* log3("Then run 'ship stack restack' again to push.");
189026
+ }
189027
+ return;
189028
+ }
189029
+ if (!json2) {
189030
+ yield* log3("Pushing bookmarks...");
189031
+ }
188965
189032
  const stackAfter = yield* vcs.getStack().pipe(
188966
- map17((s) => s.length),
188967
- catchAll2(() => succeed7(changes2.length))
189033
+ catchAll2(() => succeed7([]))
188968
189034
  );
189035
+ const bookmarksToPush = stackAfter.flatMap((c) => c.bookmarks).filter((b3) => b3 && b3.length > 0);
189036
+ const pushedBookmarks = [];
189037
+ for (const bookmark of bookmarksToPush) {
189038
+ const pushResult = yield* vcs.push(bookmark).pipe(
189039
+ map17(() => ({ success: true })),
189040
+ catchAll2((e2) => succeed7({ success: false, error: formatEffectError(e2) }))
189041
+ );
189042
+ pushedBookmarks.push({
189043
+ bookmark,
189044
+ success: pushResult.success,
189045
+ error: "error" in pushResult ? pushResult.error : void 0
189046
+ });
189047
+ }
189048
+ const allPushed = pushedBookmarks.every((p4) => p4.success);
189049
+ const anyPushed = pushedBookmarks.some((p4) => p4.success);
188969
189050
  const trunkResult = yield* vcs.getTrunkInfo().pipe(
188970
189051
  map17((trunk) => ({ success: true, trunk })),
188971
189052
  catchAll2(() => succeed7({ success: false }))
188972
189053
  );
188973
- const output = trunkResult.success ? {
188974
- restacked: true,
188975
- stackSize: stackAfter,
188976
- trunkChangeId: trunkResult.trunk.shortChangeId,
188977
- conflicted: rebaseResult.conflicted
188978
- } : {
189054
+ const output = {
189055
+ fetched: true,
188979
189056
  restacked: true,
188980
- stackSize: stackAfter,
188981
- conflicted: rebaseResult.conflicted
189057
+ pushed: anyPushed,
189058
+ stackSize: stackAfter.length,
189059
+ trunkChangeId: trunkResult.success ? trunkResult.trunk.shortChangeId : void 0,
189060
+ conflicted: false,
189061
+ pushedBookmarks: pushedBookmarks.length > 0 ? pushedBookmarks : void 0
188982
189062
  };
188983
189063
  if (json2) {
188984
189064
  yield* log3(JSON.stringify(output, null, 2));
188985
189065
  } else {
188986
- if (rebaseResult.conflicted) {
188987
- yield* log3("Restack completed with conflicts!");
188988
- yield* log3(` Rebased: yes (with conflicts)`);
188989
- if (trunkResult.success) {
188990
- yield* log3(` Trunk: ${trunkResult.trunk.shortChangeId.slice(0, 12)}`);
189066
+ yield* log3("Restack completed successfully.");
189067
+ yield* log3(` Fetched: yes`);
189068
+ yield* log3(` Rebased: ${changes2.length} change(s)`);
189069
+ if (trunkResult.success) {
189070
+ yield* log3(` Trunk: ${trunkResult.trunk.shortChangeId.slice(0, 12)}`);
189071
+ }
189072
+ yield* log3(` Stack: ${stackAfter.length} change(s)`);
189073
+ if (pushedBookmarks.length > 0) {
189074
+ const successCount = pushedBookmarks.filter((p4) => p4.success).length;
189075
+ yield* log3(` Pushed: ${successCount}/${pushedBookmarks.length} bookmark(s)`);
189076
+ if (!allPushed) {
189077
+ yield* log3("");
189078
+ yield* log3("Failed to push:");
189079
+ for (const p4 of pushedBookmarks.filter((p5) => !p5.success)) {
189080
+ yield* log3(` - ${p4.bookmark}: ${p4.error}`);
189081
+ }
188991
189082
  }
188992
- yield* log3(` Stack: ${stackAfter} change(s)`);
188993
- yield* log3("");
188994
- yield* log3("Resolve conflicts with 'jj status' and edit the conflicted files.");
188995
189083
  } else {
188996
- yield* log3("Restack completed successfully.");
188997
- yield* log3(` Rebased: ${changes2.length} change(s)`);
188998
- if (trunkResult.success) {
188999
- yield* log3(` Trunk: ${trunkResult.trunk.shortChangeId.slice(0, 12)}`);
189000
- }
189001
- yield* log3(` Stack: ${stackAfter} change(s)`);
189084
+ yield* log3(` Pushed: no bookmarks to push`);
189002
189085
  }
189003
189086
  }
189004
189087
  })
@@ -190140,7 +190223,7 @@ Commands:
190140
190223
  describe Update change description
190141
190224
  bookmark Create or move a bookmark on current change
190142
190225
  sync Fetch and rebase onto trunk
190143
- restack Rebase entire stack onto trunk (no fetch)
190226
+ restack Fetch, rebase, and push entire stack (like Graphite)
190144
190227
  submit Push and create/update PR
190145
190228
  squash Squash current change into parent
190146
190229
  abandon Abandon a change
@@ -190310,7 +190393,7 @@ Repository: ${repoName}
190310
190393
  Title: ${prTitle}
190311
190394
  URL: ${prUrl}
190312
190395
 
190313
- \u2192 Action: Run stack-sync --auto-submit to rebase and push dependent PRs`;
190396
+ \u2192 Action: Run stack-restack to rebase and push dependent PRs`;
190314
190397
  }
190315
190398
  return `[GitHub] PR #${prNumber} closed (not merged) by @${senderLogin}
190316
190399
 
@@ -192815,7 +192898,7 @@ var command = ship.pipe(
192815
192898
  prCommand
192816
192899
  ])
192817
192900
  );
192818
- var version = "0.1.11" ;
192901
+ var version = "0.1.12" ;
192819
192902
  var run9 = run8(command, {
192820
192903
  name: "ship",
192821
192904
  version
@@ -194504,7 +194587,7 @@ All support optional \`workdir\` param.
194504
194587
  | Action | Params | Description |
194505
194588
  |--------|--------|-------------|
194506
194589
  | \`stack-sync\` | - | Fetch + rebase onto trunk |
194507
- | \`stack-restack\` | - | Rebase onto trunk (no fetch) |
194590
+ | \`stack-restack\` | - | Fetch + rebase + push entire stack (like Graphite restack) |
194508
194591
  | \`stack-create\` | message?, bookmark?, noWorkspace? | New change (creates workspace by default) |
194509
194592
  | \`stack-describe\` | title, description? OR message | Update description (use title+description for proper multi-line commits) |
194510
194593
  | \`stack-submit\` | draft? | Push + create/update PR |
@@ -194702,7 +194785,7 @@ Details: ${e2.message}`,
194702
194785
  });
194703
194786
  }
194704
194787
  return new PartialShipConfig({
194705
- // provider defaults to "linear" in schema
194788
+ provider: yaml.provider ?? "linear",
194706
194789
  linear: yaml.linear ? some2(
194707
194790
  new LinearConfig({
194708
194791
  teamId: asTeamId(yaml.linear.teamId),
@@ -194710,8 +194793,13 @@ Details: ${e2.message}`,
194710
194793
  projectId: yaml.linear.projectId ? some2(asProjectId(yaml.linear.projectId)) : none2()
194711
194794
  })
194712
194795
  ) : none2(),
194713
- notion: none2(),
194714
- // TODO: Parse notion config from yaml when implemented
194796
+ notion: yaml.notion ? some2(
194797
+ new NotionConfig({
194798
+ databaseId: yaml.notion.databaseId,
194799
+ workspaceId: yaml.notion.workspaceId ? some2(yaml.notion.workspaceId) : none2(),
194800
+ propertyMapping: new NotionPropertyMapping({})
194801
+ })
194802
+ ) : none2(),
194715
194803
  auth: yaml.auth ? some2(new AuthConfig({ apiKey: yaml.auth.apiKey })) : none2()
194716
194804
  });
194717
194805
  };
@@ -194752,17 +194840,37 @@ Details: ${e2.message}`,
194752
194840
  });
194753
194841
  const load = () => gen2(function* () {
194754
194842
  const yaml = yield* readYaml();
194755
- if (!yaml || !yaml.linear || !yaml.auth) {
194843
+ if (!yaml || !yaml.auth) {
194756
194844
  return yield* fail7(WorkspaceNotInitializedError.default);
194757
194845
  }
194846
+ const provider = yaml.provider ?? "linear";
194847
+ if (provider === "linear" && !yaml.linear) {
194848
+ return yield* fail7(WorkspaceNotInitializedError.default);
194849
+ }
194850
+ if (provider === "notion" && !yaml.notion) {
194851
+ return yield* fail7(WorkspaceNotInitializedError.default);
194852
+ }
194853
+ const linearConfig = yaml.linear ? new LinearConfig({
194854
+ teamId: asTeamId(yaml.linear.teamId),
194855
+ teamKey: yaml.linear.teamKey,
194856
+ projectId: yaml.linear.projectId ? some2(asProjectId(yaml.linear.projectId)) : none2()
194857
+ }) : new LinearConfig({
194858
+ teamId: asTeamId("notion-workspace"),
194859
+ teamKey: "NOTION",
194860
+ projectId: none2()
194861
+ });
194862
+ const notionConfig = yaml.notion ? some2(
194863
+ new NotionConfig({
194864
+ databaseId: yaml.notion.databaseId,
194865
+ workspaceId: yaml.notion.workspaceId ? some2(yaml.notion.workspaceId) : none2(),
194866
+ // Use defaults from NotionPropertyMapping, override with yaml values if present
194867
+ propertyMapping: new NotionPropertyMapping({})
194868
+ })
194869
+ ) : none2();
194758
194870
  return new ShipConfig({
194759
- linear: new LinearConfig({
194760
- teamId: asTeamId(yaml.linear.teamId),
194761
- teamKey: yaml.linear.teamKey,
194762
- projectId: yaml.linear.projectId ? some2(asProjectId(yaml.linear.projectId)) : none2()
194763
- }),
194764
- notion: none2(),
194765
- // TODO: Parse notion config from yaml when implemented
194871
+ provider,
194872
+ linear: linearConfig,
194873
+ notion: notionConfig,
194766
194874
  auth: new AuthConfig({ apiKey: yaml.auth.apiKey }),
194767
194875
  git: new GitConfig({ defaultBranch: yaml.git?.defaultBranch ?? "main" }),
194768
194876
  pr: new PrConfig({ openBrowser: yaml.pr?.openBrowser ?? true }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ship-cli/core",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Linear + jj workflow CLI for AI agents",