@anthropologies/claudestory 0.1.57 → 0.1.58

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 (3) hide show
  1. package/dist/cli.js +49 -37
  2. package/dist/mcp.js +48 -36
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -5667,7 +5667,8 @@ function refreshLease(state) {
5667
5667
  contextPressure: {
5668
5668
  ...state.contextPressure,
5669
5669
  guideCallCount: newCallCount,
5670
- ticketsCompleted: state.completedTickets?.length ?? 0
5670
+ // ISS-084: Include resolved issues in work count
5671
+ ticketsCompleted: (state.completedTickets?.length ?? 0) + (state.resolvedIssues?.length ?? 0)
5671
5672
  }
5672
5673
  };
5673
5674
  }
@@ -5885,7 +5886,7 @@ var init_state_machine = __esm({
5885
5886
  VERIFY: ["FINALIZE", "IMPLEMENT", "VERIFY"],
5886
5887
  // pass → FINALIZE, fail → IMPLEMENT, retry
5887
5888
  FINALIZE: ["COMPLETE", "PICK_TICKET"],
5888
- // PICK_TICKET for issue-fix flow (bypass COMPLETE)
5889
+ // ISS-084: issues now route through COMPLETE too; PICK_TICKET kept for in-flight session compat
5889
5890
  COMPLETE: ["PICK_TICKET", "HANDOVER", "ISSUE_SWEEP", "SESSION_END"],
5890
5891
  ISSUE_FIX: ["FINALIZE", "PICK_TICKET", "ISSUE_FIX"],
5891
5892
  // T-153: fix done → FINALIZE, cancel → PICK_TICKET, retry self
@@ -5905,7 +5906,7 @@ var init_state_machine = __esm({
5905
5906
  // src/autonomous/context-pressure.ts
5906
5907
  function evaluatePressure(state) {
5907
5908
  const calls = state.contextPressure?.guideCallCount ?? state.guideCallCount ?? 0;
5908
- const tickets = state.contextPressure?.ticketsCompleted ?? state.completedTickets?.length ?? 0;
5909
+ const tickets = (state.completedTickets?.length ?? 0) + (state.resolvedIssues?.length ?? 0);
5909
5910
  const eventsBytes = state.contextPressure?.eventsLogBytes ?? 0;
5910
5911
  const tier = state.config?.compactThreshold ?? "high";
5911
5912
  const t = THRESHOLDS[tier] ?? THRESHOLDS["high"];
@@ -6448,17 +6449,22 @@ var init_pick_ticket = __esm({
6448
6449
  (c, i) => `${i + 1}. **${c.ticket.id}: ${c.ticket.title}** (${c.ticket.type})`
6449
6450
  ).join("\n");
6450
6451
  }
6451
- const highIssues = projectState.issues.filter(
6452
- (i) => i.status === "open" && (i.severity === "critical" || i.severity === "high")
6453
- );
6452
+ const allOpenIssues = projectState.issues.filter((i) => i.status === "open");
6453
+ const highIssues = allOpenIssues.filter((i) => i.severity === "critical" || i.severity === "high");
6454
+ const otherIssues = allOpenIssues.filter((i) => i.severity !== "critical" && i.severity !== "high");
6454
6455
  let issuesText = "";
6455
6456
  if (highIssues.length > 0) {
6456
6457
  issuesText = "\n\n## Open Issues (high+ severity)\n\n" + highIssues.map(
6457
6458
  (i, idx) => `${idx + 1}. **${i.id}: ${i.title}** (${i.severity})`
6458
6459
  ).join("\n");
6459
6460
  }
6461
+ if (otherIssues.length > 0) {
6462
+ issuesText += "\n\n## Open Issues (medium/low)\n\n" + otherIssues.map(
6463
+ (i, idx) => `${idx + 1}. **${i.id}: ${i.title}** (${i.severity})`
6464
+ ).join("\n");
6465
+ }
6460
6466
  const topCandidate = candidates.kind === "found" ? candidates.candidates[0] : null;
6461
- const hasIssues = highIssues.length > 0;
6467
+ const hasIssues = allOpenIssues.length > 0;
6462
6468
  if (!topCandidate && candidates.kind !== "found" && !hasIssues) {
6463
6469
  return { action: "goto", target: "COMPLETE" };
6464
6470
  }
@@ -6479,7 +6485,7 @@ var init_pick_ticket = __esm({
6479
6485
  "",
6480
6486
  "Or to fix an issue:",
6481
6487
  "```json",
6482
- `{ "sessionId": "${ctx.state.sessionId}", "action": "report", "report": { "completedAction": "issue_picked", "issueId": "${highIssues[0].id}" } }`,
6488
+ `{ "sessionId": "${ctx.state.sessionId}", "action": "report", "report": { "completedAction": "issue_picked", "issueId": "${(highIssues[0] ?? allOpenIssues[0]).id}" } }`,
6483
6489
  "```"
6484
6490
  ] : []
6485
6491
  ].join("\n"),
@@ -7798,7 +7804,7 @@ var init_finalize = __esm({
7798
7804
  }
7799
7805
  });
7800
7806
  ctx.appendEvent("commit", { commitHash: normalizedHash, issueId: currentIssue.id });
7801
- return { action: "goto", target: "PICK_TICKET" };
7807
+ return { action: "goto", target: "COMPLETE" };
7802
7808
  }
7803
7809
  const completedTicket = ctx.state.ticket ? { id: ctx.state.ticket.id, title: ctx.state.ticket.title, commitHash: normalizedHash, risk: ctx.state.ticket.risk, realizedRisk: ctx.state.ticket.realizedRisk } : void 0;
7804
7810
  ctx.writeState({
@@ -7836,6 +7842,8 @@ var init_complete = __esm({
7836
7842
  finalizeCheckpoint: null
7837
7843
  });
7838
7844
  const ticketsDone = ctx.state.completedTickets.length;
7845
+ const issuesDone = (ctx.state.resolvedIssues ?? []).length;
7846
+ const totalWorkDone = ticketsDone + issuesDone;
7839
7847
  const maxTickets = ctx.state.config.maxTicketsPerSession;
7840
7848
  const mode = ctx.state.mode ?? "auto";
7841
7849
  if (mode !== "auto") {
@@ -7856,15 +7864,17 @@ var init_complete = __esm({
7856
7864
  };
7857
7865
  }
7858
7866
  const handoverInterval = ctx.state.config.handoverInterval ?? 5;
7859
- if (handoverInterval > 0 && ticketsDone > 0 && ticketsDone % handoverInterval === 0) {
7867
+ if (handoverInterval > 0 && totalWorkDone > 0 && totalWorkDone % handoverInterval === 0) {
7860
7868
  try {
7861
7869
  const { handleHandoverCreate: handleHandoverCreate3 } = await Promise.resolve().then(() => (init_handover(), handover_exports));
7862
7870
  const completedIds = ctx.state.completedTickets.map((t) => t.id).join(", ");
7871
+ const resolvedIds = (ctx.state.resolvedIssues ?? []).join(", ");
7863
7872
  const content = [
7864
- `# Checkpoint \u2014 ${ticketsDone} tickets completed`,
7873
+ `# Checkpoint \u2014 ${totalWorkDone} items completed`,
7865
7874
  "",
7866
7875
  `**Session:** ${ctx.state.sessionId}`,
7867
- `**Tickets:** ${completedIds}`,
7876
+ ...completedIds ? [`**Tickets:** ${completedIds}`] : [],
7877
+ ...resolvedIds ? [`**Issues resolved:** ${resolvedIds}`] : [],
7868
7878
  "",
7869
7879
  "This is an automatic mid-session checkpoint. The session is still active."
7870
7880
  ].join("\n");
@@ -7878,24 +7888,19 @@ var init_complete = __esm({
7878
7888
  await saveSnapshot2(ctx.root, loadResult);
7879
7889
  } catch {
7880
7890
  }
7881
- ctx.appendEvent("checkpoint", { ticketsDone, interval: handoverInterval });
7891
+ ctx.appendEvent("checkpoint", { ticketsDone, issuesDone, totalWorkDone, interval: handoverInterval });
7882
7892
  }
7893
+ const { state: projectState } = await ctx.loadProject();
7883
7894
  let nextTarget;
7884
- if (maxTickets > 0 && ticketsDone >= maxTickets) {
7895
+ if (maxTickets > 0 && totalWorkDone >= maxTickets) {
7885
7896
  nextTarget = "HANDOVER";
7886
7897
  } else {
7887
- nextTarget = "PICK_TICKET";
7888
- }
7889
- const { state: projectState } = await ctx.loadProject();
7890
- const nextResult = nextTickets(projectState, 1);
7891
- if (nextResult.kind !== "found") {
7892
- const highIssues = projectState.issues.filter(
7893
- (i) => i.status === "open" && (i.severity === "critical" || i.severity === "high")
7894
- );
7895
- if (highIssues.length > 0) {
7898
+ const nextResult = nextTickets(projectState, 1);
7899
+ if (nextResult.kind === "found") {
7896
7900
  nextTarget = "PICK_TICKET";
7897
7901
  } else {
7898
- nextTarget = "HANDOVER";
7902
+ const openIssues = projectState.issues.filter((i) => i.status === "open");
7903
+ nextTarget = openIssues.length > 0 ? "PICK_TICKET" : "HANDOVER";
7899
7904
  }
7900
7905
  }
7901
7906
  if (nextTarget === "HANDOVER") {
@@ -7910,7 +7915,7 @@ var init_complete = __esm({
7910
7915
  target: "HANDOVER",
7911
7916
  result: {
7912
7917
  instruction: [
7913
- `# Session Complete \u2014 ${ticketsDone} ticket(s) done`,
7918
+ `# Session Complete \u2014 ${ticketsDone} ticket(s) and ${issuesDone} issue(s) done`,
7914
7919
  "",
7915
7920
  "Write a session handover summarizing what was accomplished, decisions made, and what's next.",
7916
7921
  "",
@@ -7979,6 +7984,7 @@ var init_lesson_capture = __esm({
7979
7984
  const planReviews = ctx.state.reviews.plan ?? [];
7980
7985
  const codeReviews = ctx.state.reviews.code ?? [];
7981
7986
  const ticketsDone = ctx.state.completedTickets.length;
7987
+ const issuesDone = (ctx.state.resolvedIssues ?? []).length;
7982
7988
  const planFindings = planReviews.reduce((sum, r) => sum + (r.findingCount ?? 0), 0);
7983
7989
  const planCritical = planReviews.reduce((sum, r) => sum + (r.criticalCount ?? 0), 0);
7984
7990
  const planMajor = planReviews.reduce((sum, r) => sum + (r.majorCount ?? 0), 0);
@@ -8000,7 +8006,7 @@ var init_lesson_capture = __esm({
8000
8006
  instruction: [
8001
8007
  "# Capture Lessons from Review Findings",
8002
8008
  "",
8003
- `This session completed ${ticketsDone} ticket(s). Review summary:`,
8009
+ `This session completed ${ticketsDone} ticket(s) and ${issuesDone} issue(s). Review summary:`,
8004
8010
  `- **Plan reviews:** ${planReviews.length} round(s), ${planCritical} critical, ${planMajor} major, ${planFindings} total findings`,
8005
8011
  `- **Code reviews:** ${codeReviews.length} round(s), ${codeCritical} critical, ${codeMajor} major, ${codeFindings} total findings`,
8006
8012
  "",
@@ -8231,9 +8237,10 @@ var init_handover2 = __esm({
8231
8237
  id = "HANDOVER";
8232
8238
  async enter(ctx) {
8233
8239
  const ticketsDone = ctx.state.completedTickets.length;
8240
+ const issuesDone = (ctx.state.resolvedIssues ?? []).length;
8234
8241
  return {
8235
8242
  instruction: [
8236
- `# Session Complete \u2014 ${ticketsDone} ticket(s) done`,
8243
+ `# Session Complete \u2014 ${ticketsDone} ticket(s) and ${issuesDone} issue(s) done`,
8237
8244
  "",
8238
8245
  "Write a session handover summarizing what was accomplished, decisions made, and what's next.",
8239
8246
  "",
@@ -8280,18 +8287,22 @@ var init_handover2 = __esm({
8280
8287
  });
8281
8288
  ctx.appendEvent("session_end", {
8282
8289
  ticketsCompleted: ctx.state.completedTickets.length,
8290
+ issuesResolved: (ctx.state.resolvedIssues ?? []).length,
8283
8291
  handoverFailed
8284
8292
  });
8285
8293
  const ticketsDone = ctx.state.completedTickets.length;
8294
+ const issuesDone = (ctx.state.resolvedIssues ?? []).length;
8295
+ const resolvedList = (ctx.state.resolvedIssues ?? []).map((id) => `- ${id} (resolved)`).join("\n");
8286
8296
  return {
8287
8297
  action: "advance",
8288
8298
  result: {
8289
8299
  instruction: [
8290
8300
  "# Session Complete",
8291
8301
  "",
8292
- `${ticketsDone} ticket(s) completed.${handoverFailed ? " Handover creation failed \u2014 fallback saved to session directory." : " Handover written."}${stashPopFailed ? " Auto-stash pop failed \u2014 run `git stash pop` manually." : ""} Session ended.`,
8302
+ `${ticketsDone} ticket(s) and ${issuesDone} issue(s) completed.${handoverFailed ? " Handover creation failed \u2014 fallback saved to session directory." : " Handover written."}${stashPopFailed ? " Auto-stash pop failed \u2014 run `git stash pop` manually." : ""} Session ended.`,
8293
8303
  "",
8294
- ctx.state.completedTickets.map((t) => `- ${t.id}${t.title ? `: ${t.title}` : ""} (${t.commitHash ?? "no commit"})`).join("\n")
8304
+ ctx.state.completedTickets.map((t) => `- ${t.id}${t.title ? `: ${t.title}` : ""} (${t.commitHash ?? "no commit"})`).join("\n"),
8305
+ ...resolvedList ? [resolvedList] : []
8295
8306
  ].join("\n"),
8296
8307
  reminders: [],
8297
8308
  transitionedFrom: "HANDOVER"
@@ -8372,7 +8383,7 @@ function getInstalledVersion() {
8372
8383
  }
8373
8384
  }
8374
8385
  function getRunningVersion() {
8375
- return "0.1.57";
8386
+ return "0.1.58";
8376
8387
  }
8377
8388
  var init_version_check = __esm({
8378
8389
  "src/autonomous/version-check.ts"() {
@@ -9318,7 +9329,7 @@ ${driftPreamble}Recovered to state: **${mapping.state}**. Continue from here.`,
9318
9329
  instruction: [
9319
9330
  "# Resumed After Compact \u2014 Continue Working",
9320
9331
  "",
9321
- `${written.completedTickets.length} ticket(s) done so far. Context compacted. Pick the next ticket immediately.`,
9332
+ `${written.completedTickets.length} ticket(s) and ${(written.resolvedIssues ?? []).length} issue(s) done so far. Context compacted. Pick the next ticket or issue immediately.`,
9322
9333
  "",
9323
9334
  candidatesText,
9324
9335
  "",
@@ -9434,7 +9445,8 @@ async function handleCancel(root, args) {
9434
9445
  return guideError(new Error("Session already ended."));
9435
9446
  }
9436
9447
  const isAutoMode = info.state.mode === "auto" || !info.state.mode;
9437
- const hasTicketsRemaining = info.state.config.maxTicketsPerSession === 0 || info.state.completedTickets.length < info.state.config.maxTicketsPerSession;
9448
+ const totalDone = info.state.completedTickets.length + (info.state.resolvedIssues?.length ?? 0);
9449
+ const hasTicketsRemaining = info.state.config.maxTicketsPerSession === 0 || totalDone < info.state.config.maxTicketsPerSession;
9438
9450
  const isWorkingState = !["SESSION_END", "HANDOVER", "COMPACT"].includes(info.state.state);
9439
9451
  if (isAutoMode && hasTicketsRemaining && isWorkingState) {
9440
9452
  return {
@@ -9443,7 +9455,7 @@ async function handleCancel(root, args) {
9443
9455
  text: [
9444
9456
  "# Cancel Rejected \u2014 Session Still Active",
9445
9457
  "",
9446
- `You have completed ${info.state.completedTickets.length} ticket(s) with more work remaining.`,
9458
+ `You have completed ${info.state.completedTickets.length} ticket(s) and ${(info.state.resolvedIssues ?? []).length} issue(s) with more work remaining.`,
9447
9459
  "Do NOT cancel an autonomous session due to context size.",
9448
9460
  "If you need to manage context, Claude Code handles compaction automatically.",
9449
9461
  "",
@@ -9511,14 +9523,14 @@ async function handleCancel(root, args) {
9511
9523
  });
9512
9524
  const stashNote = stashPopFailed ? " Auto-stash pop failed \u2014 run `git stash pop` manually." : "";
9513
9525
  return {
9514
- content: [{ type: "text", text: `Session ${args.sessionId} cancelled. ${written.completedTickets.length} ticket(s) were completed.${stashNote}` }]
9526
+ content: [{ type: "text", text: `Session ${args.sessionId} cancelled. ${written.completedTickets.length} ticket(s) and ${(written.resolvedIssues ?? []).length} issue(s) were completed.${stashNote}` }]
9515
9527
  };
9516
9528
  }
9517
9529
  function guideResult(state, currentState, opts) {
9518
9530
  const summary = {
9519
9531
  ticket: state.ticket ? `${state.ticket.id}: ${state.ticket.title}` : "none",
9520
9532
  risk: state.ticket?.risk ?? "unknown",
9521
- completed: state.completedTickets.map((t) => t.id),
9533
+ completed: [...state.completedTickets.map((t) => t.id), ...state.resolvedIssues ?? []],
9522
9534
  currentStep: currentState,
9523
9535
  contextPressure: state.contextPressure?.level ?? "low",
9524
9536
  branch: state.git?.branch ?? null
@@ -10969,7 +10981,7 @@ var init_mcp = __esm({
10969
10981
  init_init();
10970
10982
  ENV_VAR2 = "CLAUDESTORY_PROJECT_ROOT";
10971
10983
  CONFIG_PATH2 = ".story/config.json";
10972
- version = "0.1.57";
10984
+ version = "0.1.58";
10973
10985
  main().catch((err) => {
10974
10986
  process.stderr.write(`Fatal: ${err instanceof Error ? err.message : String(err)}
10975
10987
  `);
@@ -14451,7 +14463,7 @@ async function runCli() {
14451
14463
  registerSessionCommand: registerSessionCommand2,
14452
14464
  registerRepairCommand: registerRepairCommand2
14453
14465
  } = await Promise.resolve().then(() => (init_register(), register_exports));
14454
- const version2 = "0.1.57";
14466
+ const version2 = "0.1.58";
14455
14467
  class HandledError extends Error {
14456
14468
  constructor() {
14457
14469
  super("HANDLED_ERROR");
package/dist/mcp.js CHANGED
@@ -3912,7 +3912,8 @@ function refreshLease(state) {
3912
3912
  contextPressure: {
3913
3913
  ...state.contextPressure,
3914
3914
  guideCallCount: newCallCount,
3915
- ticketsCompleted: state.completedTickets?.length ?? 0
3915
+ // ISS-084: Include resolved issues in work count
3916
+ ticketsCompleted: (state.completedTickets?.length ?? 0) + (state.resolvedIssues?.length ?? 0)
3916
3917
  }
3917
3918
  };
3918
3919
  }
@@ -5469,7 +5470,7 @@ var TRANSITIONS = {
5469
5470
  VERIFY: ["FINALIZE", "IMPLEMENT", "VERIFY"],
5470
5471
  // pass → FINALIZE, fail → IMPLEMENT, retry
5471
5472
  FINALIZE: ["COMPLETE", "PICK_TICKET"],
5472
- // PICK_TICKET for issue-fix flow (bypass COMPLETE)
5473
+ // ISS-084: issues now route through COMPLETE too; PICK_TICKET kept for in-flight session compat
5473
5474
  COMPLETE: ["PICK_TICKET", "HANDOVER", "ISSUE_SWEEP", "SESSION_END"],
5474
5475
  ISSUE_FIX: ["FINALIZE", "PICK_TICKET", "ISSUE_FIX"],
5475
5476
  // T-153: fix done → FINALIZE, cancel → PICK_TICKET, retry self
@@ -5515,7 +5516,7 @@ var THRESHOLDS = {
5515
5516
  };
5516
5517
  function evaluatePressure(state) {
5517
5518
  const calls = state.contextPressure?.guideCallCount ?? state.guideCallCount ?? 0;
5518
- const tickets = state.contextPressure?.ticketsCompleted ?? state.completedTickets?.length ?? 0;
5519
+ const tickets = (state.completedTickets?.length ?? 0) + (state.resolvedIssues?.length ?? 0);
5519
5520
  const eventsBytes = state.contextPressure?.eventsLogBytes ?? 0;
5520
5521
  const tier = state.config?.compactThreshold ?? "high";
5521
5522
  const t = THRESHOLDS[tier] ?? THRESHOLDS["high"];
@@ -6003,17 +6004,22 @@ var PickTicketStage = class {
6003
6004
  (c, i) => `${i + 1}. **${c.ticket.id}: ${c.ticket.title}** (${c.ticket.type})`
6004
6005
  ).join("\n");
6005
6006
  }
6006
- const highIssues = projectState.issues.filter(
6007
- (i) => i.status === "open" && (i.severity === "critical" || i.severity === "high")
6008
- );
6007
+ const allOpenIssues = projectState.issues.filter((i) => i.status === "open");
6008
+ const highIssues = allOpenIssues.filter((i) => i.severity === "critical" || i.severity === "high");
6009
+ const otherIssues = allOpenIssues.filter((i) => i.severity !== "critical" && i.severity !== "high");
6009
6010
  let issuesText = "";
6010
6011
  if (highIssues.length > 0) {
6011
6012
  issuesText = "\n\n## Open Issues (high+ severity)\n\n" + highIssues.map(
6012
6013
  (i, idx) => `${idx + 1}. **${i.id}: ${i.title}** (${i.severity})`
6013
6014
  ).join("\n");
6014
6015
  }
6016
+ if (otherIssues.length > 0) {
6017
+ issuesText += "\n\n## Open Issues (medium/low)\n\n" + otherIssues.map(
6018
+ (i, idx) => `${idx + 1}. **${i.id}: ${i.title}** (${i.severity})`
6019
+ ).join("\n");
6020
+ }
6015
6021
  const topCandidate = candidates.kind === "found" ? candidates.candidates[0] : null;
6016
- const hasIssues = highIssues.length > 0;
6022
+ const hasIssues = allOpenIssues.length > 0;
6017
6023
  if (!topCandidate && candidates.kind !== "found" && !hasIssues) {
6018
6024
  return { action: "goto", target: "COMPLETE" };
6019
6025
  }
@@ -6034,7 +6040,7 @@ var PickTicketStage = class {
6034
6040
  "",
6035
6041
  "Or to fix an issue:",
6036
6042
  "```json",
6037
- `{ "sessionId": "${ctx.state.sessionId}", "action": "report", "report": { "completedAction": "issue_picked", "issueId": "${highIssues[0].id}" } }`,
6043
+ `{ "sessionId": "${ctx.state.sessionId}", "action": "report", "report": { "completedAction": "issue_picked", "issueId": "${(highIssues[0] ?? allOpenIssues[0]).id}" } }`,
6038
6044
  "```"
6039
6045
  ] : []
6040
6046
  ].join("\n"),
@@ -7292,7 +7298,7 @@ var FinalizeStage = class {
7292
7298
  }
7293
7299
  });
7294
7300
  ctx.appendEvent("commit", { commitHash: normalizedHash, issueId: currentIssue.id });
7295
- return { action: "goto", target: "PICK_TICKET" };
7301
+ return { action: "goto", target: "COMPLETE" };
7296
7302
  }
7297
7303
  const completedTicket = ctx.state.ticket ? { id: ctx.state.ticket.id, title: ctx.state.ticket.title, commitHash: normalizedHash, risk: ctx.state.ticket.risk, realizedRisk: ctx.state.ticket.realizedRisk } : void 0;
7298
7304
  ctx.writeState({
@@ -7322,6 +7328,8 @@ var CompleteStage = class {
7322
7328
  finalizeCheckpoint: null
7323
7329
  });
7324
7330
  const ticketsDone = ctx.state.completedTickets.length;
7331
+ const issuesDone = (ctx.state.resolvedIssues ?? []).length;
7332
+ const totalWorkDone = ticketsDone + issuesDone;
7325
7333
  const maxTickets = ctx.state.config.maxTicketsPerSession;
7326
7334
  const mode = ctx.state.mode ?? "auto";
7327
7335
  if (mode !== "auto") {
@@ -7342,15 +7350,17 @@ var CompleteStage = class {
7342
7350
  };
7343
7351
  }
7344
7352
  const handoverInterval = ctx.state.config.handoverInterval ?? 5;
7345
- if (handoverInterval > 0 && ticketsDone > 0 && ticketsDone % handoverInterval === 0) {
7353
+ if (handoverInterval > 0 && totalWorkDone > 0 && totalWorkDone % handoverInterval === 0) {
7346
7354
  try {
7347
7355
  const { handleHandoverCreate: handleHandoverCreate3 } = await Promise.resolve().then(() => (init_handover(), handover_exports));
7348
7356
  const completedIds = ctx.state.completedTickets.map((t) => t.id).join(", ");
7357
+ const resolvedIds = (ctx.state.resolvedIssues ?? []).join(", ");
7349
7358
  const content = [
7350
- `# Checkpoint \u2014 ${ticketsDone} tickets completed`,
7359
+ `# Checkpoint \u2014 ${totalWorkDone} items completed`,
7351
7360
  "",
7352
7361
  `**Session:** ${ctx.state.sessionId}`,
7353
- `**Tickets:** ${completedIds}`,
7362
+ ...completedIds ? [`**Tickets:** ${completedIds}`] : [],
7363
+ ...resolvedIds ? [`**Issues resolved:** ${resolvedIds}`] : [],
7354
7364
  "",
7355
7365
  "This is an automatic mid-session checkpoint. The session is still active."
7356
7366
  ].join("\n");
@@ -7364,24 +7374,19 @@ var CompleteStage = class {
7364
7374
  await saveSnapshot2(ctx.root, loadResult);
7365
7375
  } catch {
7366
7376
  }
7367
- ctx.appendEvent("checkpoint", { ticketsDone, interval: handoverInterval });
7377
+ ctx.appendEvent("checkpoint", { ticketsDone, issuesDone, totalWorkDone, interval: handoverInterval });
7368
7378
  }
7379
+ const { state: projectState } = await ctx.loadProject();
7369
7380
  let nextTarget;
7370
- if (maxTickets > 0 && ticketsDone >= maxTickets) {
7381
+ if (maxTickets > 0 && totalWorkDone >= maxTickets) {
7371
7382
  nextTarget = "HANDOVER";
7372
7383
  } else {
7373
- nextTarget = "PICK_TICKET";
7374
- }
7375
- const { state: projectState } = await ctx.loadProject();
7376
- const nextResult = nextTickets(projectState, 1);
7377
- if (nextResult.kind !== "found") {
7378
- const highIssues = projectState.issues.filter(
7379
- (i) => i.status === "open" && (i.severity === "critical" || i.severity === "high")
7380
- );
7381
- if (highIssues.length > 0) {
7384
+ const nextResult = nextTickets(projectState, 1);
7385
+ if (nextResult.kind === "found") {
7382
7386
  nextTarget = "PICK_TICKET";
7383
7387
  } else {
7384
- nextTarget = "HANDOVER";
7388
+ const openIssues = projectState.issues.filter((i) => i.status === "open");
7389
+ nextTarget = openIssues.length > 0 ? "PICK_TICKET" : "HANDOVER";
7385
7390
  }
7386
7391
  }
7387
7392
  if (nextTarget === "HANDOVER") {
@@ -7396,7 +7401,7 @@ var CompleteStage = class {
7396
7401
  target: "HANDOVER",
7397
7402
  result: {
7398
7403
  instruction: [
7399
- `# Session Complete \u2014 ${ticketsDone} ticket(s) done`,
7404
+ `# Session Complete \u2014 ${ticketsDone} ticket(s) and ${issuesDone} issue(s) done`,
7400
7405
  "",
7401
7406
  "Write a session handover summarizing what was accomplished, decisions made, and what's next.",
7402
7407
  "",
@@ -7459,6 +7464,7 @@ var LessonCaptureStage = class {
7459
7464
  const planReviews = ctx.state.reviews.plan ?? [];
7460
7465
  const codeReviews = ctx.state.reviews.code ?? [];
7461
7466
  const ticketsDone = ctx.state.completedTickets.length;
7467
+ const issuesDone = (ctx.state.resolvedIssues ?? []).length;
7462
7468
  const planFindings = planReviews.reduce((sum, r) => sum + (r.findingCount ?? 0), 0);
7463
7469
  const planCritical = planReviews.reduce((sum, r) => sum + (r.criticalCount ?? 0), 0);
7464
7470
  const planMajor = planReviews.reduce((sum, r) => sum + (r.majorCount ?? 0), 0);
@@ -7480,7 +7486,7 @@ var LessonCaptureStage = class {
7480
7486
  instruction: [
7481
7487
  "# Capture Lessons from Review Findings",
7482
7488
  "",
7483
- `This session completed ${ticketsDone} ticket(s). Review summary:`,
7489
+ `This session completed ${ticketsDone} ticket(s) and ${issuesDone} issue(s). Review summary:`,
7484
7490
  `- **Plan reviews:** ${planReviews.length} round(s), ${planCritical} critical, ${planMajor} major, ${planFindings} total findings`,
7485
7491
  `- **Code reviews:** ${codeReviews.length} round(s), ${codeCritical} critical, ${codeMajor} major, ${codeFindings} total findings`,
7486
7492
  "",
@@ -7692,9 +7698,10 @@ var HandoverStage = class {
7692
7698
  id = "HANDOVER";
7693
7699
  async enter(ctx) {
7694
7700
  const ticketsDone = ctx.state.completedTickets.length;
7701
+ const issuesDone = (ctx.state.resolvedIssues ?? []).length;
7695
7702
  return {
7696
7703
  instruction: [
7697
- `# Session Complete \u2014 ${ticketsDone} ticket(s) done`,
7704
+ `# Session Complete \u2014 ${ticketsDone} ticket(s) and ${issuesDone} issue(s) done`,
7698
7705
  "",
7699
7706
  "Write a session handover summarizing what was accomplished, decisions made, and what's next.",
7700
7707
  "",
@@ -7741,18 +7748,22 @@ var HandoverStage = class {
7741
7748
  });
7742
7749
  ctx.appendEvent("session_end", {
7743
7750
  ticketsCompleted: ctx.state.completedTickets.length,
7751
+ issuesResolved: (ctx.state.resolvedIssues ?? []).length,
7744
7752
  handoverFailed
7745
7753
  });
7746
7754
  const ticketsDone = ctx.state.completedTickets.length;
7755
+ const issuesDone = (ctx.state.resolvedIssues ?? []).length;
7756
+ const resolvedList = (ctx.state.resolvedIssues ?? []).map((id) => `- ${id} (resolved)`).join("\n");
7747
7757
  return {
7748
7758
  action: "advance",
7749
7759
  result: {
7750
7760
  instruction: [
7751
7761
  "# Session Complete",
7752
7762
  "",
7753
- `${ticketsDone} ticket(s) completed.${handoverFailed ? " Handover creation failed \u2014 fallback saved to session directory." : " Handover written."}${stashPopFailed ? " Auto-stash pop failed \u2014 run `git stash pop` manually." : ""} Session ended.`,
7763
+ `${ticketsDone} ticket(s) and ${issuesDone} issue(s) completed.${handoverFailed ? " Handover creation failed \u2014 fallback saved to session directory." : " Handover written."}${stashPopFailed ? " Auto-stash pop failed \u2014 run `git stash pop` manually." : ""} Session ended.`,
7754
7764
  "",
7755
- ctx.state.completedTickets.map((t) => `- ${t.id}${t.title ? `: ${t.title}` : ""} (${t.commitHash ?? "no commit"})`).join("\n")
7765
+ ctx.state.completedTickets.map((t) => `- ${t.id}${t.title ? `: ${t.title}` : ""} (${t.commitHash ?? "no commit"})`).join("\n"),
7766
+ ...resolvedList ? [resolvedList] : []
7756
7767
  ].join("\n"),
7757
7768
  reminders: [],
7758
7769
  transitionedFrom: "HANDOVER"
@@ -7816,7 +7827,7 @@ function getInstalledVersion() {
7816
7827
  }
7817
7828
  }
7818
7829
  function getRunningVersion() {
7819
- return "0.1.57";
7830
+ return "0.1.58";
7820
7831
  }
7821
7832
 
7822
7833
  // src/autonomous/guide.ts
@@ -8779,7 +8790,7 @@ ${driftPreamble}Recovered to state: **${mapping.state}**. Continue from here.`,
8779
8790
  instruction: [
8780
8791
  "# Resumed After Compact \u2014 Continue Working",
8781
8792
  "",
8782
- `${written.completedTickets.length} ticket(s) done so far. Context compacted. Pick the next ticket immediately.`,
8793
+ `${written.completedTickets.length} ticket(s) and ${(written.resolvedIssues ?? []).length} issue(s) done so far. Context compacted. Pick the next ticket or issue immediately.`,
8783
8794
  "",
8784
8795
  candidatesText,
8785
8796
  "",
@@ -8895,7 +8906,8 @@ async function handleCancel(root, args) {
8895
8906
  return guideError(new Error("Session already ended."));
8896
8907
  }
8897
8908
  const isAutoMode = info.state.mode === "auto" || !info.state.mode;
8898
- const hasTicketsRemaining = info.state.config.maxTicketsPerSession === 0 || info.state.completedTickets.length < info.state.config.maxTicketsPerSession;
8909
+ const totalDone = info.state.completedTickets.length + (info.state.resolvedIssues?.length ?? 0);
8910
+ const hasTicketsRemaining = info.state.config.maxTicketsPerSession === 0 || totalDone < info.state.config.maxTicketsPerSession;
8899
8911
  const isWorkingState = !["SESSION_END", "HANDOVER", "COMPACT"].includes(info.state.state);
8900
8912
  if (isAutoMode && hasTicketsRemaining && isWorkingState) {
8901
8913
  return {
@@ -8904,7 +8916,7 @@ async function handleCancel(root, args) {
8904
8916
  text: [
8905
8917
  "# Cancel Rejected \u2014 Session Still Active",
8906
8918
  "",
8907
- `You have completed ${info.state.completedTickets.length} ticket(s) with more work remaining.`,
8919
+ `You have completed ${info.state.completedTickets.length} ticket(s) and ${(info.state.resolvedIssues ?? []).length} issue(s) with more work remaining.`,
8908
8920
  "Do NOT cancel an autonomous session due to context size.",
8909
8921
  "If you need to manage context, Claude Code handles compaction automatically.",
8910
8922
  "",
@@ -8972,14 +8984,14 @@ async function handleCancel(root, args) {
8972
8984
  });
8973
8985
  const stashNote = stashPopFailed ? " Auto-stash pop failed \u2014 run `git stash pop` manually." : "";
8974
8986
  return {
8975
- content: [{ type: "text", text: `Session ${args.sessionId} cancelled. ${written.completedTickets.length} ticket(s) were completed.${stashNote}` }]
8987
+ content: [{ type: "text", text: `Session ${args.sessionId} cancelled. ${written.completedTickets.length} ticket(s) and ${(written.resolvedIssues ?? []).length} issue(s) were completed.${stashNote}` }]
8976
8988
  };
8977
8989
  }
8978
8990
  function guideResult(state, currentState, opts) {
8979
8991
  const summary = {
8980
8992
  ticket: state.ticket ? `${state.ticket.id}: ${state.ticket.title}` : "none",
8981
8993
  risk: state.ticket?.risk ?? "unknown",
8982
- completed: state.completedTickets.map((t) => t.id),
8994
+ completed: [...state.completedTickets.map((t) => t.id), ...state.resolvedIssues ?? []],
8983
8995
  currentStep: currentState,
8984
8996
  contextPressure: state.contextPressure?.level ?? "low",
8985
8997
  branch: state.git?.branch ?? null
@@ -10087,7 +10099,7 @@ async function ensureGitignoreEntries(gitignorePath, entries) {
10087
10099
  // src/mcp/index.ts
10088
10100
  var ENV_VAR2 = "CLAUDESTORY_PROJECT_ROOT";
10089
10101
  var CONFIG_PATH2 = ".story/config.json";
10090
- var version = "0.1.57";
10102
+ var version = "0.1.58";
10091
10103
  function tryDiscoverRoot() {
10092
10104
  const envRoot = process.env[ENV_VAR2];
10093
10105
  if (envRoot) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anthropologies/claudestory",
3
- "version": "0.1.57",
3
+ "version": "0.1.58",
4
4
  "license": "PolyForm-Noncommercial-1.0.0",
5
5
  "description": "An agentic development framework. Track tickets, issues, and progress for your project so every session builds on the last.",
6
6
  "homepage": "https://claudestory.com",