@anthropologies/claudestory 0.1.15 → 0.1.16
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/cli.js +114 -6
- package/dist/mcp.js +177 -5
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -562,6 +562,29 @@ var init_handover_parser = __esm({
|
|
|
562
562
|
});
|
|
563
563
|
|
|
564
564
|
// src/core/project-loader.ts
|
|
565
|
+
var project_loader_exports = {};
|
|
566
|
+
__export(project_loader_exports, {
|
|
567
|
+
atomicWrite: () => atomicWrite,
|
|
568
|
+
deleteIssue: () => deleteIssue,
|
|
569
|
+
deleteNote: () => deleteNote,
|
|
570
|
+
deleteTicket: () => deleteTicket,
|
|
571
|
+
guardPath: () => guardPath,
|
|
572
|
+
loadProject: () => loadProject,
|
|
573
|
+
runTransaction: () => runTransaction,
|
|
574
|
+
runTransactionUnlocked: () => runTransactionUnlocked,
|
|
575
|
+
serializeJSON: () => serializeJSON,
|
|
576
|
+
sortKeysDeep: () => sortKeysDeep,
|
|
577
|
+
withProjectLock: () => withProjectLock,
|
|
578
|
+
writeConfig: () => writeConfig,
|
|
579
|
+
writeIssue: () => writeIssue,
|
|
580
|
+
writeIssueUnlocked: () => writeIssueUnlocked,
|
|
581
|
+
writeNote: () => writeNote,
|
|
582
|
+
writeNoteUnlocked: () => writeNoteUnlocked,
|
|
583
|
+
writeRoadmap: () => writeRoadmap,
|
|
584
|
+
writeRoadmapUnlocked: () => writeRoadmapUnlocked,
|
|
585
|
+
writeTicket: () => writeTicket,
|
|
586
|
+
writeTicketUnlocked: () => writeTicketUnlocked
|
|
587
|
+
});
|
|
565
588
|
import {
|
|
566
589
|
readdir as readdir2,
|
|
567
590
|
readFile as readFile2,
|
|
@@ -920,6 +943,12 @@ async function runTransactionUnlocked(root, operations) {
|
|
|
920
943
|
throw new ProjectLoaderError("io_error", "Transaction failed", err);
|
|
921
944
|
}
|
|
922
945
|
}
|
|
946
|
+
async function runTransaction(root, operations) {
|
|
947
|
+
const wrapDir = resolve2(root, ".story");
|
|
948
|
+
await withLock(wrapDir, async () => {
|
|
949
|
+
await runTransactionUnlocked(root, operations);
|
|
950
|
+
});
|
|
951
|
+
}
|
|
923
952
|
async function doRecoverTransaction(wrapDir) {
|
|
924
953
|
const journalPath = join3(wrapDir, ".txn.json");
|
|
925
954
|
let entries;
|
|
@@ -5237,6 +5266,19 @@ async function handleReportPlan(root, dir, state, report) {
|
|
|
5237
5266
|
});
|
|
5238
5267
|
}
|
|
5239
5268
|
const risk = assessRisk(void 0, void 0);
|
|
5269
|
+
if (state.ticket) {
|
|
5270
|
+
try {
|
|
5271
|
+
const { withProjectLock: withProjectLock2, writeTicketUnlocked: writeTicketUnlocked2 } = await Promise.resolve().then(() => (init_project_loader(), project_loader_exports));
|
|
5272
|
+
await withProjectLock2(root, { strict: false }, async ({ state: projectState }) => {
|
|
5273
|
+
const ticket = projectState.ticketByID(state.ticket.id);
|
|
5274
|
+
if (ticket && ticket.status !== "inprogress") {
|
|
5275
|
+
const updated = { ...ticket, status: "inprogress" };
|
|
5276
|
+
await writeTicketUnlocked2(updated, root);
|
|
5277
|
+
}
|
|
5278
|
+
});
|
|
5279
|
+
} catch {
|
|
5280
|
+
}
|
|
5281
|
+
}
|
|
5240
5282
|
const written = writeSessionSync(dir, {
|
|
5241
5283
|
...state,
|
|
5242
5284
|
state: "PLAN_REVIEW",
|
|
@@ -5594,11 +5636,11 @@ async function handleReportComplete(root, dir, state, report) {
|
|
|
5594
5636
|
const maxTickets = updated.config.maxTicketsPerSession;
|
|
5595
5637
|
let nextState;
|
|
5596
5638
|
let advice = "ok";
|
|
5597
|
-
if (
|
|
5639
|
+
if (maxTickets > 0 && ticketsDone >= maxTickets) {
|
|
5598
5640
|
nextState = "HANDOVER";
|
|
5599
|
-
|
|
5600
|
-
} else if (maxTickets > 0 && ticketsDone >= maxTickets) {
|
|
5641
|
+
} else if (pressure === "critical") {
|
|
5601
5642
|
nextState = "HANDOVER";
|
|
5643
|
+
advice = "compact-now";
|
|
5602
5644
|
} else if (pressure === "high") {
|
|
5603
5645
|
advice = "consider-compact";
|
|
5604
5646
|
nextState = "PICK_TICKET";
|
|
@@ -5678,6 +5720,36 @@ async function handleReportHandover(root, dir, state, report) {
|
|
|
5678
5720
|
} catch {
|
|
5679
5721
|
}
|
|
5680
5722
|
}
|
|
5723
|
+
const pressureLevel = state.contextPressure?.level ?? "low";
|
|
5724
|
+
const maxTickets = state.config.maxTicketsPerSession;
|
|
5725
|
+
const capReached = maxTickets > 0 && state.completedTickets.length >= maxTickets;
|
|
5726
|
+
let hasMoreTickets = false;
|
|
5727
|
+
try {
|
|
5728
|
+
const { state: ps } = await loadProject(root);
|
|
5729
|
+
hasMoreTickets = nextTickets(ps, 1).kind === "found";
|
|
5730
|
+
} catch {
|
|
5731
|
+
}
|
|
5732
|
+
if (pressureLevel === "critical" && hasMoreTickets && !capReached) {
|
|
5733
|
+
return guideResult(state, "HANDOVER", {
|
|
5734
|
+
instruction: [
|
|
5735
|
+
"# Context Compaction Needed",
|
|
5736
|
+
"",
|
|
5737
|
+
`${state.completedTickets.length} ticket(s) completed so far. Handover written. Context is large \u2014 time to compact and continue.`,
|
|
5738
|
+
"",
|
|
5739
|
+
'Call `claudestory_autonomous_guide` with `action: "pre_compact"` now:',
|
|
5740
|
+
"```json",
|
|
5741
|
+
`{ "sessionId": "${state.sessionId}", "action": "pre_compact" }`,
|
|
5742
|
+
"```",
|
|
5743
|
+
"",
|
|
5744
|
+
'After pre_compact responds, run `/compact`, then call with `action: "resume"` to continue working on more tickets.'
|
|
5745
|
+
].join("\n"),
|
|
5746
|
+
reminders: [
|
|
5747
|
+
"Do NOT stop. This is a context compaction, not a session end.",
|
|
5748
|
+
"Call pre_compact \u2192 /compact \u2192 resume to continue autonomous work."
|
|
5749
|
+
],
|
|
5750
|
+
contextAdvice: "compact-now"
|
|
5751
|
+
});
|
|
5752
|
+
}
|
|
5681
5753
|
const written = writeSessionSync(dir, {
|
|
5682
5754
|
...state,
|
|
5683
5755
|
state: "SESSION_END",
|
|
@@ -5725,6 +5797,40 @@ async function handleResume(root, args) {
|
|
|
5725
5797
|
resumeFromRevision: null,
|
|
5726
5798
|
contextPressure: { ...info.state.contextPressure, compactionCount: (info.state.contextPressure?.compactionCount ?? 0) + 1 }
|
|
5727
5799
|
});
|
|
5800
|
+
if (resumeState === "PICK_TICKET") {
|
|
5801
|
+
let candidatesText = "No ticket candidates available.";
|
|
5802
|
+
let topCandidate = null;
|
|
5803
|
+
try {
|
|
5804
|
+
const { state: ps } = await loadProject(root);
|
|
5805
|
+
const result = nextTickets(ps, 5);
|
|
5806
|
+
if (result.kind === "found") {
|
|
5807
|
+
topCandidate = result.candidates[0] ?? null;
|
|
5808
|
+
candidatesText = result.candidates.map(
|
|
5809
|
+
(c, i) => `${i + 1}. **${c.ticket.id}: ${c.ticket.title}** (${c.ticket.type})`
|
|
5810
|
+
).join("\n");
|
|
5811
|
+
}
|
|
5812
|
+
} catch {
|
|
5813
|
+
}
|
|
5814
|
+
return guideResult(written, "PICK_TICKET", {
|
|
5815
|
+
instruction: [
|
|
5816
|
+
"# Resumed After Compact \u2014 Continue Working",
|
|
5817
|
+
"",
|
|
5818
|
+
`${written.completedTickets.length} ticket(s) done so far. Context compacted. Pick the next ticket immediately.`,
|
|
5819
|
+
"",
|
|
5820
|
+
candidatesText,
|
|
5821
|
+
"",
|
|
5822
|
+
topCandidate ? `Pick **${topCandidate.ticket.id}** by calling \`claudestory_autonomous_guide\` now:` : "Pick a ticket now:",
|
|
5823
|
+
"```json",
|
|
5824
|
+
topCandidate ? `{ "sessionId": "${written.sessionId}", "action": "report", "report": { "completedAction": "ticket_picked", "ticketId": "${topCandidate.ticket.id}" } }` : `{ "sessionId": "${written.sessionId}", "action": "report", "report": { "completedAction": "ticket_picked", "ticketId": "T-XXX" } }`,
|
|
5825
|
+
"```"
|
|
5826
|
+
].join("\n"),
|
|
5827
|
+
reminders: [
|
|
5828
|
+
"Do NOT stop or summarize. Pick the next ticket IMMEDIATELY.",
|
|
5829
|
+
"Do NOT ask the user for confirmation.",
|
|
5830
|
+
"You are in autonomous mode \u2014 continue working."
|
|
5831
|
+
]
|
|
5832
|
+
});
|
|
5833
|
+
}
|
|
5728
5834
|
return guideResult(written, resumeState, {
|
|
5729
5835
|
instruction: [
|
|
5730
5836
|
"# Resumed After Compact",
|
|
@@ -5736,6 +5842,7 @@ async function handleResume(root, args) {
|
|
|
5736
5842
|
].join("\n"),
|
|
5737
5843
|
reminders: [
|
|
5738
5844
|
"Do NOT use plan mode.",
|
|
5845
|
+
"Do NOT stop or summarize.",
|
|
5739
5846
|
"Call autonomous_guide after completing each step."
|
|
5740
5847
|
]
|
|
5741
5848
|
});
|
|
@@ -5751,11 +5858,12 @@ async function handlePreCompact(root, args) {
|
|
|
5751
5858
|
return guideError(new Error(`Session ${args.sessionId} is already in COMPACT state. Call action: "resume" to continue.`));
|
|
5752
5859
|
}
|
|
5753
5860
|
const headResult = await gitHead(root);
|
|
5861
|
+
const resumeTarget = info.state.state === "HANDOVER" ? "PICK_TICKET" : info.state.state;
|
|
5754
5862
|
const written = writeSessionSync(info.dir, {
|
|
5755
5863
|
...refreshLease(info.state),
|
|
5756
5864
|
state: "COMPACT",
|
|
5757
5865
|
previousState: info.state.state,
|
|
5758
|
-
preCompactState:
|
|
5866
|
+
preCompactState: resumeTarget,
|
|
5759
5867
|
resumeFromRevision: info.state.revision,
|
|
5760
5868
|
git: {
|
|
5761
5869
|
...info.state.git,
|
|
@@ -6835,7 +6943,7 @@ var init_mcp = __esm({
|
|
|
6835
6943
|
init_init();
|
|
6836
6944
|
ENV_VAR2 = "CLAUDESTORY_PROJECT_ROOT";
|
|
6837
6945
|
CONFIG_PATH2 = ".story/config.json";
|
|
6838
|
-
version = "0.1.
|
|
6946
|
+
version = "0.1.16";
|
|
6839
6947
|
main().catch((err) => {
|
|
6840
6948
|
process.stderr.write(`Fatal: ${err instanceof Error ? err.message : String(err)}
|
|
6841
6949
|
`);
|
|
@@ -9470,7 +9578,7 @@ async function runCli() {
|
|
|
9470
9578
|
registerHookStatusCommand: registerHookStatusCommand2,
|
|
9471
9579
|
registerConfigCommand: registerConfigCommand2
|
|
9472
9580
|
} = await Promise.resolve().then(() => (init_register(), register_exports));
|
|
9473
|
-
const version2 = "0.1.
|
|
9581
|
+
const version2 = "0.1.16";
|
|
9474
9582
|
class HandledError extends Error {
|
|
9475
9583
|
constructor() {
|
|
9476
9584
|
super("HANDLED_ERROR");
|
package/dist/mcp.js
CHANGED
|
@@ -504,6 +504,29 @@ var init_handover_parser = __esm({
|
|
|
504
504
|
});
|
|
505
505
|
|
|
506
506
|
// src/core/project-loader.ts
|
|
507
|
+
var project_loader_exports = {};
|
|
508
|
+
__export(project_loader_exports, {
|
|
509
|
+
atomicWrite: () => atomicWrite,
|
|
510
|
+
deleteIssue: () => deleteIssue,
|
|
511
|
+
deleteNote: () => deleteNote,
|
|
512
|
+
deleteTicket: () => deleteTicket,
|
|
513
|
+
guardPath: () => guardPath,
|
|
514
|
+
loadProject: () => loadProject,
|
|
515
|
+
runTransaction: () => runTransaction,
|
|
516
|
+
runTransactionUnlocked: () => runTransactionUnlocked,
|
|
517
|
+
serializeJSON: () => serializeJSON,
|
|
518
|
+
sortKeysDeep: () => sortKeysDeep,
|
|
519
|
+
withProjectLock: () => withProjectLock,
|
|
520
|
+
writeConfig: () => writeConfig,
|
|
521
|
+
writeIssue: () => writeIssue,
|
|
522
|
+
writeIssueUnlocked: () => writeIssueUnlocked,
|
|
523
|
+
writeNote: () => writeNote,
|
|
524
|
+
writeNoteUnlocked: () => writeNoteUnlocked,
|
|
525
|
+
writeRoadmap: () => writeRoadmap,
|
|
526
|
+
writeRoadmapUnlocked: () => writeRoadmapUnlocked,
|
|
527
|
+
writeTicket: () => writeTicket,
|
|
528
|
+
writeTicketUnlocked: () => writeTicketUnlocked
|
|
529
|
+
});
|
|
507
530
|
import {
|
|
508
531
|
readdir as readdir2,
|
|
509
532
|
readFile as readFile2,
|
|
@@ -807,6 +830,67 @@ async function withProjectLock(root, options, handler) {
|
|
|
807
830
|
await handler(result);
|
|
808
831
|
});
|
|
809
832
|
}
|
|
833
|
+
async function runTransactionUnlocked(root, operations) {
|
|
834
|
+
const wrapDir = resolve2(root, ".story");
|
|
835
|
+
const journalPath = join3(wrapDir, ".txn.json");
|
|
836
|
+
const entries = [];
|
|
837
|
+
let commitStarted = false;
|
|
838
|
+
try {
|
|
839
|
+
for (const op of operations) {
|
|
840
|
+
if (op.op === "write") {
|
|
841
|
+
const tempPath = `${op.target}.${process.pid}.tmp`;
|
|
842
|
+
entries.push({ op: "write", target: op.target, tempPath });
|
|
843
|
+
} else {
|
|
844
|
+
entries.push({ op: "delete", target: op.target });
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
const journal = { entries, commitStarted: false };
|
|
848
|
+
await fsyncWrite(journalPath, JSON.stringify(journal, null, 2));
|
|
849
|
+
for (const op of operations) {
|
|
850
|
+
if (op.op === "write") {
|
|
851
|
+
const tempPath = `${op.target}.${process.pid}.tmp`;
|
|
852
|
+
await fsyncWrite(tempPath, op.content);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
journal.commitStarted = true;
|
|
856
|
+
await fsyncWrite(journalPath, JSON.stringify(journal, null, 2));
|
|
857
|
+
commitStarted = true;
|
|
858
|
+
for (const entry of entries) {
|
|
859
|
+
if (entry.op === "write" && entry.tempPath) {
|
|
860
|
+
await rename(entry.tempPath, entry.target);
|
|
861
|
+
} else if (entry.op === "delete") {
|
|
862
|
+
try {
|
|
863
|
+
await unlink(entry.target);
|
|
864
|
+
} catch {
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
await unlink(journalPath);
|
|
869
|
+
} catch (err) {
|
|
870
|
+
if (!commitStarted) {
|
|
871
|
+
for (const entry of entries) {
|
|
872
|
+
if (entry.tempPath) {
|
|
873
|
+
try {
|
|
874
|
+
await unlink(entry.tempPath);
|
|
875
|
+
} catch {
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
try {
|
|
880
|
+
await unlink(journalPath);
|
|
881
|
+
} catch {
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
if (err instanceof ProjectLoaderError) throw err;
|
|
885
|
+
throw new ProjectLoaderError("io_error", "Transaction failed", err);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
async function runTransaction(root, operations) {
|
|
889
|
+
const wrapDir = resolve2(root, ".story");
|
|
890
|
+
await withLock(wrapDir, async () => {
|
|
891
|
+
await runTransactionUnlocked(root, operations);
|
|
892
|
+
});
|
|
893
|
+
}
|
|
810
894
|
async function doRecoverTransaction(wrapDir) {
|
|
811
895
|
const journalPath = join3(wrapDir, ".txn.json");
|
|
812
896
|
let entries;
|
|
@@ -996,6 +1080,15 @@ async function atomicWrite(targetPath, content) {
|
|
|
996
1080
|
);
|
|
997
1081
|
}
|
|
998
1082
|
}
|
|
1083
|
+
async function fsyncWrite(filePath, content) {
|
|
1084
|
+
const fh = await open(filePath, "w");
|
|
1085
|
+
try {
|
|
1086
|
+
await fh.writeFile(content, "utf-8");
|
|
1087
|
+
await fh.sync();
|
|
1088
|
+
} finally {
|
|
1089
|
+
await fh.close();
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
999
1092
|
async function guardPath(target, root) {
|
|
1000
1093
|
let resolvedRoot;
|
|
1001
1094
|
try {
|
|
@@ -4739,6 +4832,19 @@ async function handleReportPlan(root, dir, state, report) {
|
|
|
4739
4832
|
});
|
|
4740
4833
|
}
|
|
4741
4834
|
const risk = assessRisk(void 0, void 0);
|
|
4835
|
+
if (state.ticket) {
|
|
4836
|
+
try {
|
|
4837
|
+
const { withProjectLock: withProjectLock2, writeTicketUnlocked: writeTicketUnlocked2 } = await Promise.resolve().then(() => (init_project_loader(), project_loader_exports));
|
|
4838
|
+
await withProjectLock2(root, { strict: false }, async ({ state: projectState }) => {
|
|
4839
|
+
const ticket = projectState.ticketByID(state.ticket.id);
|
|
4840
|
+
if (ticket && ticket.status !== "inprogress") {
|
|
4841
|
+
const updated = { ...ticket, status: "inprogress" };
|
|
4842
|
+
await writeTicketUnlocked2(updated, root);
|
|
4843
|
+
}
|
|
4844
|
+
});
|
|
4845
|
+
} catch {
|
|
4846
|
+
}
|
|
4847
|
+
}
|
|
4742
4848
|
const written = writeSessionSync(dir, {
|
|
4743
4849
|
...state,
|
|
4744
4850
|
state: "PLAN_REVIEW",
|
|
@@ -5096,11 +5202,11 @@ async function handleReportComplete(root, dir, state, report) {
|
|
|
5096
5202
|
const maxTickets = updated.config.maxTicketsPerSession;
|
|
5097
5203
|
let nextState;
|
|
5098
5204
|
let advice = "ok";
|
|
5099
|
-
if (
|
|
5205
|
+
if (maxTickets > 0 && ticketsDone >= maxTickets) {
|
|
5100
5206
|
nextState = "HANDOVER";
|
|
5101
|
-
|
|
5102
|
-
} else if (maxTickets > 0 && ticketsDone >= maxTickets) {
|
|
5207
|
+
} else if (pressure === "critical") {
|
|
5103
5208
|
nextState = "HANDOVER";
|
|
5209
|
+
advice = "compact-now";
|
|
5104
5210
|
} else if (pressure === "high") {
|
|
5105
5211
|
advice = "consider-compact";
|
|
5106
5212
|
nextState = "PICK_TICKET";
|
|
@@ -5180,6 +5286,36 @@ async function handleReportHandover(root, dir, state, report) {
|
|
|
5180
5286
|
} catch {
|
|
5181
5287
|
}
|
|
5182
5288
|
}
|
|
5289
|
+
const pressureLevel = state.contextPressure?.level ?? "low";
|
|
5290
|
+
const maxTickets = state.config.maxTicketsPerSession;
|
|
5291
|
+
const capReached = maxTickets > 0 && state.completedTickets.length >= maxTickets;
|
|
5292
|
+
let hasMoreTickets = false;
|
|
5293
|
+
try {
|
|
5294
|
+
const { state: ps } = await loadProject(root);
|
|
5295
|
+
hasMoreTickets = nextTickets(ps, 1).kind === "found";
|
|
5296
|
+
} catch {
|
|
5297
|
+
}
|
|
5298
|
+
if (pressureLevel === "critical" && hasMoreTickets && !capReached) {
|
|
5299
|
+
return guideResult(state, "HANDOVER", {
|
|
5300
|
+
instruction: [
|
|
5301
|
+
"# Context Compaction Needed",
|
|
5302
|
+
"",
|
|
5303
|
+
`${state.completedTickets.length} ticket(s) completed so far. Handover written. Context is large \u2014 time to compact and continue.`,
|
|
5304
|
+
"",
|
|
5305
|
+
'Call `claudestory_autonomous_guide` with `action: "pre_compact"` now:',
|
|
5306
|
+
"```json",
|
|
5307
|
+
`{ "sessionId": "${state.sessionId}", "action": "pre_compact" }`,
|
|
5308
|
+
"```",
|
|
5309
|
+
"",
|
|
5310
|
+
'After pre_compact responds, run `/compact`, then call with `action: "resume"` to continue working on more tickets.'
|
|
5311
|
+
].join("\n"),
|
|
5312
|
+
reminders: [
|
|
5313
|
+
"Do NOT stop. This is a context compaction, not a session end.",
|
|
5314
|
+
"Call pre_compact \u2192 /compact \u2192 resume to continue autonomous work."
|
|
5315
|
+
],
|
|
5316
|
+
contextAdvice: "compact-now"
|
|
5317
|
+
});
|
|
5318
|
+
}
|
|
5183
5319
|
const written = writeSessionSync(dir, {
|
|
5184
5320
|
...state,
|
|
5185
5321
|
state: "SESSION_END",
|
|
@@ -5227,6 +5363,40 @@ async function handleResume(root, args) {
|
|
|
5227
5363
|
resumeFromRevision: null,
|
|
5228
5364
|
contextPressure: { ...info.state.contextPressure, compactionCount: (info.state.contextPressure?.compactionCount ?? 0) + 1 }
|
|
5229
5365
|
});
|
|
5366
|
+
if (resumeState === "PICK_TICKET") {
|
|
5367
|
+
let candidatesText = "No ticket candidates available.";
|
|
5368
|
+
let topCandidate = null;
|
|
5369
|
+
try {
|
|
5370
|
+
const { state: ps } = await loadProject(root);
|
|
5371
|
+
const result = nextTickets(ps, 5);
|
|
5372
|
+
if (result.kind === "found") {
|
|
5373
|
+
topCandidate = result.candidates[0] ?? null;
|
|
5374
|
+
candidatesText = result.candidates.map(
|
|
5375
|
+
(c, i) => `${i + 1}. **${c.ticket.id}: ${c.ticket.title}** (${c.ticket.type})`
|
|
5376
|
+
).join("\n");
|
|
5377
|
+
}
|
|
5378
|
+
} catch {
|
|
5379
|
+
}
|
|
5380
|
+
return guideResult(written, "PICK_TICKET", {
|
|
5381
|
+
instruction: [
|
|
5382
|
+
"# Resumed After Compact \u2014 Continue Working",
|
|
5383
|
+
"",
|
|
5384
|
+
`${written.completedTickets.length} ticket(s) done so far. Context compacted. Pick the next ticket immediately.`,
|
|
5385
|
+
"",
|
|
5386
|
+
candidatesText,
|
|
5387
|
+
"",
|
|
5388
|
+
topCandidate ? `Pick **${topCandidate.ticket.id}** by calling \`claudestory_autonomous_guide\` now:` : "Pick a ticket now:",
|
|
5389
|
+
"```json",
|
|
5390
|
+
topCandidate ? `{ "sessionId": "${written.sessionId}", "action": "report", "report": { "completedAction": "ticket_picked", "ticketId": "${topCandidate.ticket.id}" } }` : `{ "sessionId": "${written.sessionId}", "action": "report", "report": { "completedAction": "ticket_picked", "ticketId": "T-XXX" } }`,
|
|
5391
|
+
"```"
|
|
5392
|
+
].join("\n"),
|
|
5393
|
+
reminders: [
|
|
5394
|
+
"Do NOT stop or summarize. Pick the next ticket IMMEDIATELY.",
|
|
5395
|
+
"Do NOT ask the user for confirmation.",
|
|
5396
|
+
"You are in autonomous mode \u2014 continue working."
|
|
5397
|
+
]
|
|
5398
|
+
});
|
|
5399
|
+
}
|
|
5230
5400
|
return guideResult(written, resumeState, {
|
|
5231
5401
|
instruction: [
|
|
5232
5402
|
"# Resumed After Compact",
|
|
@@ -5238,6 +5408,7 @@ async function handleResume(root, args) {
|
|
|
5238
5408
|
].join("\n"),
|
|
5239
5409
|
reminders: [
|
|
5240
5410
|
"Do NOT use plan mode.",
|
|
5411
|
+
"Do NOT stop or summarize.",
|
|
5241
5412
|
"Call autonomous_guide after completing each step."
|
|
5242
5413
|
]
|
|
5243
5414
|
});
|
|
@@ -5253,11 +5424,12 @@ async function handlePreCompact(root, args) {
|
|
|
5253
5424
|
return guideError(new Error(`Session ${args.sessionId} is already in COMPACT state. Call action: "resume" to continue.`));
|
|
5254
5425
|
}
|
|
5255
5426
|
const headResult = await gitHead(root);
|
|
5427
|
+
const resumeTarget = info.state.state === "HANDOVER" ? "PICK_TICKET" : info.state.state;
|
|
5256
5428
|
const written = writeSessionSync(info.dir, {
|
|
5257
5429
|
...refreshLease(info.state),
|
|
5258
5430
|
state: "COMPACT",
|
|
5259
5431
|
previousState: info.state.state,
|
|
5260
|
-
preCompactState:
|
|
5432
|
+
preCompactState: resumeTarget,
|
|
5261
5433
|
resumeFromRevision: info.state.revision,
|
|
5262
5434
|
git: {
|
|
5263
5435
|
...info.state.git,
|
|
@@ -6034,7 +6206,7 @@ async function ensureGitignoreEntries(gitignorePath, entries) {
|
|
|
6034
6206
|
// src/mcp/index.ts
|
|
6035
6207
|
var ENV_VAR2 = "CLAUDESTORY_PROJECT_ROOT";
|
|
6036
6208
|
var CONFIG_PATH2 = ".story/config.json";
|
|
6037
|
-
var version = "0.1.
|
|
6209
|
+
var version = "0.1.16";
|
|
6038
6210
|
function tryDiscoverRoot() {
|
|
6039
6211
|
const envRoot = process.env[ENV_VAR2];
|
|
6040
6212
|
if (envRoot) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anthropologies/claudestory",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"description": "Cross-session context persistence for AI coding projects. Tracks tickets, issues, roadmap, and handovers so every session builds on the last.",
|
|
6
6
|
"keywords": [
|