techunter 1.2.1 → 1.2.3

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.cjs CHANGED
@@ -146943,14 +146943,14 @@ async function printTaskList(config) {
146943
146943
  const roots = childrenOf.get(null) ?? [];
146944
146944
  for (let i2 = 0; i2 < roots.length; i2++) {
146945
146945
  const isLast = i2 === roots.length - 1;
146946
- printTask2(roots[i2], "", isLast ? "\\-- " : "|-- ", isLast);
146946
+ printTask2(roots[i2], "", "", isLast);
146947
146947
  }
146948
146948
  const remaining = tasks.filter((task) => !visited.has(task.number));
146949
146949
  if (remaining.length > 0) {
146950
146950
  console.log(source_default.yellow(" Warning: task hierarchy contains orphaned or cyclic links; showing remaining tasks at root."));
146951
146951
  for (let i2 = 0; i2 < remaining.length; i2++) {
146952
146952
  const isLast = i2 === remaining.length - 1;
146953
- printTask2(remaining[i2], "", isLast ? "\\-- " : "|-- ", isLast);
146953
+ printTask2(remaining[i2], "", "", isLast);
146954
146954
  }
146955
146955
  }
146956
146956
  }
@@ -147248,8 +147248,9 @@ ${rollbackNotices.join("\n")}` : "";
147248
147248
  throw new Error(`Could not prepare task #${issue.number}: ${err.message}${details}`);
147249
147249
  }
147250
147250
  }
147251
- async function restoreTaskTransitionContext(context) {
147251
+ async function restoreTaskTransitionContext(context, options2 = {}) {
147252
147252
  const notices = [];
147253
+ const syncBranch = options2.syncBranch ?? true;
147253
147254
  try {
147254
147255
  await switchToBranchOrCreate(context.originalBranch);
147255
147256
  notices.push(`Returned to ${context.originalBranch}.`);
@@ -147260,29 +147261,33 @@ async function restoreTaskTransitionContext(context) {
147260
147261
  }
147261
147262
  return notices;
147262
147263
  }
147263
- try {
147264
- const syncResult = await syncBranchWithRemote(context.originalBranch);
147265
- if (syncResult.mode === "fast-forward") {
147266
- notices.push(`Fast-forwarded ${context.originalBranch} to the latest origin/${context.originalBranch}.`);
147267
- } else if (syncResult.mode === "merge") {
147268
- notices.push(
147269
- `Merged the latest origin/${context.originalBranch} into ${context.originalBranch} before restoring your work.`
147270
- );
147271
- }
147272
- } catch (err) {
147273
- notices.push(`Could not sync ${context.originalBranch} with origin/${context.originalBranch}: ${err.message}`);
147274
- if (context.restoreStash) {
147275
- notices.push("Your stashed work was not restored because the branch needs manual sync first.");
147276
- }
147277
- setConfig({
147278
- taskState: context.previousTaskState ?? {
147279
- activeIssueNumber: void 0,
147280
- baseCommit: void 0,
147281
- activeBranch: void 0,
147282
- resumeStack: void 0
147264
+ if (syncBranch) {
147265
+ try {
147266
+ const syncResult = await syncBranchWithRemote(context.originalBranch);
147267
+ if (syncResult.mode === "fast-forward") {
147268
+ notices.push(`Fast-forwarded ${context.originalBranch} to the latest origin/${context.originalBranch}.`);
147269
+ } else if (syncResult.mode === "merge") {
147270
+ notices.push(
147271
+ `Merged the latest origin/${context.originalBranch} into ${context.originalBranch} before restoring your work.`
147272
+ );
147283
147273
  }
147284
- });
147285
- return notices;
147274
+ } catch (err) {
147275
+ notices.push(`Could not sync ${context.originalBranch} with origin/${context.originalBranch}: ${err.message}`);
147276
+ if (context.restoreStash) {
147277
+ notices.push("Your stashed work was not restored because the branch needs manual sync first.");
147278
+ }
147279
+ setConfig({
147280
+ taskState: context.previousTaskState ?? {
147281
+ activeIssueNumber: void 0,
147282
+ baseCommit: void 0,
147283
+ activeBranch: void 0,
147284
+ resumeStack: void 0
147285
+ }
147286
+ });
147287
+ return notices;
147288
+ }
147289
+ } else {
147290
+ notices.push(`Skipped syncing ${context.originalBranch} with origin/${context.originalBranch} before restoring your work.`);
147286
147291
  }
147287
147292
  if (context.restoreStash) {
147288
147293
  try {
@@ -147611,6 +147616,7 @@ ${diff || "(no changes)"}`,
147611
147616
  var decisionSchema2 = external_exports.object({
147612
147617
  action: external_exports.enum(["restore", "stay"]),
147613
147618
  candidateIndex: external_exports.number().int().min(0).optional(),
147619
+ syncBeforeRestore: external_exports.boolean().optional(),
147614
147620
  reason: external_exports.string().min(1),
147615
147621
  confidence: external_exports.enum(["low", "medium", "high"])
147616
147622
  });
@@ -147652,14 +147658,32 @@ function buildFallbackTaskResumeDecision(candidates) {
147652
147658
  return {
147653
147659
  action: "restore",
147654
147660
  candidateIndex: restorable >= 0 ? restorable : 0,
147661
+ syncBeforeRestore: true,
147655
147662
  reason: restorable >= 0 ? "A deferred parent context has stashed work waiting to be restored." : "A deferred parent context exists, so returning there is the safest completion state.",
147656
147663
  confidence: "high",
147657
147664
  source: "heuristic"
147658
147665
  };
147659
147666
  }
147667
+ function materializeResumeContext(candidate) {
147668
+ return {
147669
+ originalBranch: candidate.originalBranch,
147670
+ restoreStash: candidate.restoreStash,
147671
+ previousTaskState: candidate.taskStateSnapshot ? {
147672
+ ...candidate.taskStateSnapshot
147673
+ } : void 0
147674
+ };
147675
+ }
147660
147676
  async function planPostSubmitResume(config, options2) {
147661
147677
  const deferredCandidates = buildResumeCandidates(options2.taskState, options2.issueNumber);
147662
- const candidates = options2.immediateRestore ? [options2.immediateRestore, ...deferredCandidates] : deferredCandidates;
147678
+ const candidates = options2.immediateRestore ? [{
147679
+ originalBranch: options2.immediateRestore.originalBranch,
147680
+ restoreStash: options2.immediateRestore.restoreStash,
147681
+ taskStateSnapshot: options2.immediateRestore.previousTaskState ? {
147682
+ activeIssueNumber: options2.immediateRestore.previousTaskState.activeIssueNumber,
147683
+ baseCommit: options2.immediateRestore.previousTaskState.baseCommit,
147684
+ activeBranch: options2.immediateRestore.previousTaskState.activeBranch
147685
+ } : void 0
147686
+ }, ...deferredCandidates] : deferredCandidates;
147663
147687
  const fallback2 = buildFallbackTaskResumeDecision(candidates);
147664
147688
  if (candidates.length === 0) {
147665
147689
  return { decision: fallback2 };
@@ -147679,7 +147703,8 @@ async function planPostSubmitResume(config, options2) {
147679
147703
  "You are deciding the best post-submit repository state for Techunter.",
147680
147704
  "Prefer restoring the most relevant deferred parent context when it contains stashed work or unfinished parent-task state.",
147681
147705
  'Choose "stay" only when staying on the current branch is clearly safer than restoring any deferred parent context.',
147682
- 'Respond with JSON only: {"action":"restore|stay","candidateIndex":0,"reason":"...","confidence":"low|medium|high"}'
147706
+ 'When action is "restore", also decide whether Techunter should sync the branch with origin before restoring stashed work.',
147707
+ 'Respond with JSON only: {"action":"restore|stay","candidateIndex":0,"syncBeforeRestore":true,"reason":"...","confidence":"low|medium|high"}'
147683
147708
  ].join("\n");
147684
147709
  const user = [
147685
147710
  `Submitted task: #${options2.issueNumber}`,
@@ -147710,14 +147735,14 @@ async function planPostSubmitResume(config, options2) {
147710
147735
  if (!content) {
147711
147736
  return {
147712
147737
  decision: fallback2,
147713
- selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? candidates[fallback2.candidateIndex] : void 0
147738
+ selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? materializeResumeContext(candidates[fallback2.candidateIndex]) : void 0
147714
147739
  };
147715
147740
  }
147716
147741
  const parsed = decisionSchema2.safeParse(JSON.parse(content));
147717
147742
  if (!parsed.success) {
147718
147743
  return {
147719
147744
  decision: fallback2,
147720
- selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? candidates[fallback2.candidateIndex] : void 0
147745
+ selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? materializeResumeContext(candidates[fallback2.candidateIndex]) : void 0
147721
147746
  };
147722
147747
  }
147723
147748
  if (parsed.data.action === "restore") {
@@ -147726,23 +147751,25 @@ async function planPostSubmitResume(config, options2) {
147726
147751
  if (!selectedContext) {
147727
147752
  return {
147728
147753
  decision: fallback2,
147729
- selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? candidates[fallback2.candidateIndex] : void 0
147754
+ selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? materializeResumeContext(candidates[fallback2.candidateIndex]) : void 0
147730
147755
  };
147731
147756
  }
147732
147757
  return {
147733
147758
  decision: {
147734
147759
  action: "restore",
147735
147760
  candidateIndex: index,
147761
+ syncBeforeRestore: parsed.data.syncBeforeRestore ?? true,
147736
147762
  reason: parsed.data.reason,
147737
147763
  confidence: parsed.data.confidence,
147738
147764
  source: "agent"
147739
147765
  },
147740
- selectedContext
147766
+ selectedContext: materializeResumeContext(selectedContext)
147741
147767
  };
147742
147768
  }
147743
147769
  return {
147744
147770
  decision: {
147745
147771
  action: "stay",
147772
+ syncBeforeRestore: void 0,
147746
147773
  reason: parsed.data.reason,
147747
147774
  confidence: parsed.data.confidence,
147748
147775
  source: "agent"
@@ -147751,7 +147778,7 @@ async function planPostSubmitResume(config, options2) {
147751
147778
  } catch {
147752
147779
  return {
147753
147780
  decision: fallback2,
147754
- selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? candidates[fallback2.candidateIndex] : void 0
147781
+ selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? materializeResumeContext(candidates[fallback2.candidateIndex]) : void 0
147755
147782
  };
147756
147783
  }
147757
147784
  }
@@ -148166,7 +148193,9 @@ async function finalizePostSubmitContext(config, issueNumber, branch, immediateR
148166
148193
  `Resume planner: ${decision.source} chose ${decision.action} (${decision.confidence}) - ${decision.reason}`
148167
148194
  ];
148168
148195
  if (decision.action === "restore" && selectedContext) {
148169
- const restored = await restoreTaskTransitionContext(selectedContext);
148196
+ const restored = await restoreTaskTransitionContext(selectedContext, {
148197
+ syncBranch: decision.syncBeforeRestore ?? true
148198
+ });
148170
148199
  return notices.concat(restored);
148171
148200
  }
148172
148201
  setConfig({
@@ -151459,7 +151488,7 @@ async function startAutoUpdate(currentVersion) {
151459
151488
  }
151460
151489
 
151461
151490
  // src/index.ts
151462
- var version = "1.2.1";
151491
+ var version = "1.2.3";
151463
151492
  var SLASH_NAMES = [
151464
151493
  "/help",
151465
151494
  "/h",
package/dist/mcp.cjs CHANGED
@@ -143805,14 +143805,14 @@ async function printTaskList(config2) {
143805
143805
  const roots = childrenOf.get(null) ?? [];
143806
143806
  for (let i2 = 0; i2 < roots.length; i2++) {
143807
143807
  const isLast = i2 === roots.length - 1;
143808
- printTask2(roots[i2], "", isLast ? "\\-- " : "|-- ", isLast);
143808
+ printTask2(roots[i2], "", "", isLast);
143809
143809
  }
143810
143810
  const remaining = tasks.filter((task) => !visited.has(task.number));
143811
143811
  if (remaining.length > 0) {
143812
143812
  console.log(source_default.yellow(" Warning: task hierarchy contains orphaned or cyclic links; showing remaining tasks at root."));
143813
143813
  for (let i2 = 0; i2 < remaining.length; i2++) {
143814
143814
  const isLast = i2 === remaining.length - 1;
143815
- printTask2(remaining[i2], "", isLast ? "\\-- " : "|-- ", isLast);
143815
+ printTask2(remaining[i2], "", "", isLast);
143816
143816
  }
143817
143817
  }
143818
143818
  }
@@ -151899,8 +151899,9 @@ ${rollbackNotices.join("\n")}` : "";
151899
151899
  throw new Error(`Could not prepare task #${issue2.number}: ${err.message}${details}`);
151900
151900
  }
151901
151901
  }
151902
- async function restoreTaskTransitionContext(context) {
151902
+ async function restoreTaskTransitionContext(context, options2 = {}) {
151903
151903
  const notices = [];
151904
+ const syncBranch = options2.syncBranch ?? true;
151904
151905
  try {
151905
151906
  await switchToBranchOrCreate(context.originalBranch);
151906
151907
  notices.push(`Returned to ${context.originalBranch}.`);
@@ -151911,29 +151912,33 @@ async function restoreTaskTransitionContext(context) {
151911
151912
  }
151912
151913
  return notices;
151913
151914
  }
151914
- try {
151915
- const syncResult = await syncBranchWithRemote(context.originalBranch);
151916
- if (syncResult.mode === "fast-forward") {
151917
- notices.push(`Fast-forwarded ${context.originalBranch} to the latest origin/${context.originalBranch}.`);
151918
- } else if (syncResult.mode === "merge") {
151919
- notices.push(
151920
- `Merged the latest origin/${context.originalBranch} into ${context.originalBranch} before restoring your work.`
151921
- );
151922
- }
151923
- } catch (err) {
151924
- notices.push(`Could not sync ${context.originalBranch} with origin/${context.originalBranch}: ${err.message}`);
151925
- if (context.restoreStash) {
151926
- notices.push("Your stashed work was not restored because the branch needs manual sync first.");
151927
- }
151928
- setConfig({
151929
- taskState: context.previousTaskState ?? {
151930
- activeIssueNumber: void 0,
151931
- baseCommit: void 0,
151932
- activeBranch: void 0,
151933
- resumeStack: void 0
151915
+ if (syncBranch) {
151916
+ try {
151917
+ const syncResult = await syncBranchWithRemote(context.originalBranch);
151918
+ if (syncResult.mode === "fast-forward") {
151919
+ notices.push(`Fast-forwarded ${context.originalBranch} to the latest origin/${context.originalBranch}.`);
151920
+ } else if (syncResult.mode === "merge") {
151921
+ notices.push(
151922
+ `Merged the latest origin/${context.originalBranch} into ${context.originalBranch} before restoring your work.`
151923
+ );
151934
151924
  }
151935
- });
151936
- return notices;
151925
+ } catch (err) {
151926
+ notices.push(`Could not sync ${context.originalBranch} with origin/${context.originalBranch}: ${err.message}`);
151927
+ if (context.restoreStash) {
151928
+ notices.push("Your stashed work was not restored because the branch needs manual sync first.");
151929
+ }
151930
+ setConfig({
151931
+ taskState: context.previousTaskState ?? {
151932
+ activeIssueNumber: void 0,
151933
+ baseCommit: void 0,
151934
+ activeBranch: void 0,
151935
+ resumeStack: void 0
151936
+ }
151937
+ });
151938
+ return notices;
151939
+ }
151940
+ } else {
151941
+ notices.push(`Skipped syncing ${context.originalBranch} with origin/${context.originalBranch} before restoring your work.`);
151937
151942
  }
151938
151943
  if (context.restoreStash) {
151939
151944
  try {
@@ -152327,6 +152332,7 @@ ${diff || "(no changes)"}`,
152327
152332
  var decisionSchema2 = external_exports.object({
152328
152333
  action: external_exports.enum(["restore", "stay"]),
152329
152334
  candidateIndex: external_exports.number().int().min(0).optional(),
152335
+ syncBeforeRestore: external_exports.boolean().optional(),
152330
152336
  reason: external_exports.string().min(1),
152331
152337
  confidence: external_exports.enum(["low", "medium", "high"])
152332
152338
  });
@@ -152368,14 +152374,32 @@ function buildFallbackTaskResumeDecision(candidates) {
152368
152374
  return {
152369
152375
  action: "restore",
152370
152376
  candidateIndex: restorable >= 0 ? restorable : 0,
152377
+ syncBeforeRestore: true,
152371
152378
  reason: restorable >= 0 ? "A deferred parent context has stashed work waiting to be restored." : "A deferred parent context exists, so returning there is the safest completion state.",
152372
152379
  confidence: "high",
152373
152380
  source: "heuristic"
152374
152381
  };
152375
152382
  }
152383
+ function materializeResumeContext(candidate) {
152384
+ return {
152385
+ originalBranch: candidate.originalBranch,
152386
+ restoreStash: candidate.restoreStash,
152387
+ previousTaskState: candidate.taskStateSnapshot ? {
152388
+ ...candidate.taskStateSnapshot
152389
+ } : void 0
152390
+ };
152391
+ }
152376
152392
  async function planPostSubmitResume(config2, options2) {
152377
152393
  const deferredCandidates = buildResumeCandidates(options2.taskState, options2.issueNumber);
152378
- const candidates = options2.immediateRestore ? [options2.immediateRestore, ...deferredCandidates] : deferredCandidates;
152394
+ const candidates = options2.immediateRestore ? [{
152395
+ originalBranch: options2.immediateRestore.originalBranch,
152396
+ restoreStash: options2.immediateRestore.restoreStash,
152397
+ taskStateSnapshot: options2.immediateRestore.previousTaskState ? {
152398
+ activeIssueNumber: options2.immediateRestore.previousTaskState.activeIssueNumber,
152399
+ baseCommit: options2.immediateRestore.previousTaskState.baseCommit,
152400
+ activeBranch: options2.immediateRestore.previousTaskState.activeBranch
152401
+ } : void 0
152402
+ }, ...deferredCandidates] : deferredCandidates;
152379
152403
  const fallback2 = buildFallbackTaskResumeDecision(candidates);
152380
152404
  if (candidates.length === 0) {
152381
152405
  return { decision: fallback2 };
@@ -152395,7 +152419,8 @@ async function planPostSubmitResume(config2, options2) {
152395
152419
  "You are deciding the best post-submit repository state for Techunter.",
152396
152420
  "Prefer restoring the most relevant deferred parent context when it contains stashed work or unfinished parent-task state.",
152397
152421
  'Choose "stay" only when staying on the current branch is clearly safer than restoring any deferred parent context.',
152398
- 'Respond with JSON only: {"action":"restore|stay","candidateIndex":0,"reason":"...","confidence":"low|medium|high"}'
152422
+ 'When action is "restore", also decide whether Techunter should sync the branch with origin before restoring stashed work.',
152423
+ 'Respond with JSON only: {"action":"restore|stay","candidateIndex":0,"syncBeforeRestore":true,"reason":"...","confidence":"low|medium|high"}'
152399
152424
  ].join("\n");
152400
152425
  const user = [
152401
152426
  `Submitted task: #${options2.issueNumber}`,
@@ -152426,14 +152451,14 @@ async function planPostSubmitResume(config2, options2) {
152426
152451
  if (!content) {
152427
152452
  return {
152428
152453
  decision: fallback2,
152429
- selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? candidates[fallback2.candidateIndex] : void 0
152454
+ selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? materializeResumeContext(candidates[fallback2.candidateIndex]) : void 0
152430
152455
  };
152431
152456
  }
152432
152457
  const parsed = decisionSchema2.safeParse(JSON.parse(content));
152433
152458
  if (!parsed.success) {
152434
152459
  return {
152435
152460
  decision: fallback2,
152436
- selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? candidates[fallback2.candidateIndex] : void 0
152461
+ selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? materializeResumeContext(candidates[fallback2.candidateIndex]) : void 0
152437
152462
  };
152438
152463
  }
152439
152464
  if (parsed.data.action === "restore") {
@@ -152442,23 +152467,25 @@ async function planPostSubmitResume(config2, options2) {
152442
152467
  if (!selectedContext) {
152443
152468
  return {
152444
152469
  decision: fallback2,
152445
- selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? candidates[fallback2.candidateIndex] : void 0
152470
+ selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? materializeResumeContext(candidates[fallback2.candidateIndex]) : void 0
152446
152471
  };
152447
152472
  }
152448
152473
  return {
152449
152474
  decision: {
152450
152475
  action: "restore",
152451
152476
  candidateIndex: index,
152477
+ syncBeforeRestore: parsed.data.syncBeforeRestore ?? true,
152452
152478
  reason: parsed.data.reason,
152453
152479
  confidence: parsed.data.confidence,
152454
152480
  source: "agent"
152455
152481
  },
152456
- selectedContext
152482
+ selectedContext: materializeResumeContext(selectedContext)
152457
152483
  };
152458
152484
  }
152459
152485
  return {
152460
152486
  decision: {
152461
152487
  action: "stay",
152488
+ syncBeforeRestore: void 0,
152462
152489
  reason: parsed.data.reason,
152463
152490
  confidence: parsed.data.confidence,
152464
152491
  source: "agent"
@@ -152467,7 +152494,7 @@ async function planPostSubmitResume(config2, options2) {
152467
152494
  } catch {
152468
152495
  return {
152469
152496
  decision: fallback2,
152470
- selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? candidates[fallback2.candidateIndex] : void 0
152497
+ selectedContext: fallback2.action === "restore" && fallback2.candidateIndex !== void 0 ? materializeResumeContext(candidates[fallback2.candidateIndex]) : void 0
152471
152498
  };
152472
152499
  }
152473
152500
  }
@@ -152882,7 +152909,9 @@ async function finalizePostSubmitContext(config2, issueNumber, branch, immediate
152882
152909
  `Resume planner: ${decision.source} chose ${decision.action} (${decision.confidence}) - ${decision.reason}`
152883
152910
  ];
152884
152911
  if (decision.action === "restore" && selectedContext) {
152885
- const restored = await restoreTaskTransitionContext(selectedContext);
152912
+ const restored = await restoreTaskTransitionContext(selectedContext, {
152913
+ syncBranch: decision.syncBeforeRestore ?? true
152914
+ });
152886
152915
  return notices.concat(restored);
152887
152916
  }
152888
152917
  setConfig({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "techunter",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "AI-powered task distribution CLI for development teams",
5
5
  "author": "Techunter Contributors",
6
6
  "license": "MIT",