@anthropologies/claudestory 0.1.34 → 0.1.35
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 +192 -13
- package/dist/mcp.js +49 -11
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3382,7 +3382,20 @@ function validateParentTicket(parentId, ticketId, state) {
|
|
|
3382
3382
|
throw new CliValidationError("invalid_input", `Parent ticket ${parentId} not found`);
|
|
3383
3383
|
}
|
|
3384
3384
|
}
|
|
3385
|
+
function buildErrorMultiset(findings) {
|
|
3386
|
+
const counts = /* @__PURE__ */ new Map();
|
|
3387
|
+
const messages = /* @__PURE__ */ new Map();
|
|
3388
|
+
for (const f of findings) {
|
|
3389
|
+
if (f.level !== "error") continue;
|
|
3390
|
+
const key = `${f.code}|${f.entity ?? ""}|${f.message}`;
|
|
3391
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
3392
|
+
messages.set(key, f.message);
|
|
3393
|
+
}
|
|
3394
|
+
return { counts, messages };
|
|
3395
|
+
}
|
|
3385
3396
|
function validatePostWriteState(candidate, state, isCreate) {
|
|
3397
|
+
const preResult = validateProject(state);
|
|
3398
|
+
const { counts: preErrors } = buildErrorMultiset(preResult.findings);
|
|
3386
3399
|
const existingTickets = [...state.tickets];
|
|
3387
3400
|
if (isCreate) {
|
|
3388
3401
|
existingTickets.push(candidate);
|
|
@@ -3399,11 +3412,17 @@ function validatePostWriteState(candidate, state, isCreate) {
|
|
|
3399
3412
|
config: state.config,
|
|
3400
3413
|
handoverFilenames: [...state.handoverFilenames]
|
|
3401
3414
|
});
|
|
3402
|
-
const
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3415
|
+
const postResult = validateProject(postState);
|
|
3416
|
+
const { counts: postErrors, messages: postMessages } = buildErrorMultiset(postResult.findings);
|
|
3417
|
+
const newErrors = [];
|
|
3418
|
+
for (const [key, postCount] of postErrors) {
|
|
3419
|
+
const preCount = preErrors.get(key) ?? 0;
|
|
3420
|
+
if (postCount > preCount) {
|
|
3421
|
+
newErrors.push(postMessages.get(key) ?? key);
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3424
|
+
if (newErrors.length > 0) {
|
|
3425
|
+
throw new CliValidationError("validation_failed", `Write would create invalid state: ${newErrors.join("; ")}`);
|
|
3407
3426
|
}
|
|
3408
3427
|
}
|
|
3409
3428
|
async function handleTicketCreate(args, format, root) {
|
|
@@ -3587,7 +3606,20 @@ function validateRelatedTickets(ids, state) {
|
|
|
3587
3606
|
}
|
|
3588
3607
|
}
|
|
3589
3608
|
}
|
|
3609
|
+
function buildErrorMultiset2(findings) {
|
|
3610
|
+
const counts = /* @__PURE__ */ new Map();
|
|
3611
|
+
const messages = /* @__PURE__ */ new Map();
|
|
3612
|
+
for (const f of findings) {
|
|
3613
|
+
if (f.level !== "error") continue;
|
|
3614
|
+
const key = `${f.code}|${f.entity ?? ""}|${f.message}`;
|
|
3615
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
3616
|
+
messages.set(key, f.message);
|
|
3617
|
+
}
|
|
3618
|
+
return { counts, messages };
|
|
3619
|
+
}
|
|
3590
3620
|
function validatePostWriteIssueState(candidate, state, isCreate) {
|
|
3621
|
+
const preResult = validateProject(state);
|
|
3622
|
+
const { counts: preErrors } = buildErrorMultiset2(preResult.findings);
|
|
3591
3623
|
const existingIssues = [...state.issues];
|
|
3592
3624
|
if (isCreate) {
|
|
3593
3625
|
existingIssues.push(candidate);
|
|
@@ -3604,11 +3636,17 @@ function validatePostWriteIssueState(candidate, state, isCreate) {
|
|
|
3604
3636
|
config: state.config,
|
|
3605
3637
|
handoverFilenames: [...state.handoverFilenames]
|
|
3606
3638
|
});
|
|
3607
|
-
const
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3639
|
+
const postResult = validateProject(postState);
|
|
3640
|
+
const { counts: postErrors, messages: postMessages } = buildErrorMultiset2(postResult.findings);
|
|
3641
|
+
const newErrors = [];
|
|
3642
|
+
for (const [key, postCount] of postErrors) {
|
|
3643
|
+
const preCount = preErrors.get(key) ?? 0;
|
|
3644
|
+
if (postCount > preCount) {
|
|
3645
|
+
newErrors.push(postMessages.get(key) ?? key);
|
|
3646
|
+
}
|
|
3647
|
+
}
|
|
3648
|
+
if (newErrors.length > 0) {
|
|
3649
|
+
throw new CliValidationError("validation_failed", `Write would create invalid state: ${newErrors.join("; ")}`);
|
|
3612
3650
|
}
|
|
3613
3651
|
}
|
|
3614
3652
|
async function handleIssueCreate(args, format, root) {
|
|
@@ -10373,7 +10411,7 @@ var init_mcp = __esm({
|
|
|
10373
10411
|
init_init();
|
|
10374
10412
|
ENV_VAR2 = "CLAUDESTORY_PROJECT_ROOT";
|
|
10375
10413
|
CONFIG_PATH2 = ".story/config.json";
|
|
10376
|
-
version = "0.1.
|
|
10414
|
+
version = "0.1.35";
|
|
10377
10415
|
main().catch((err) => {
|
|
10378
10416
|
process.stderr.write(`Fatal: ${err instanceof Error ? err.message : String(err)}
|
|
10379
10417
|
`);
|
|
@@ -10521,6 +10559,102 @@ var init_run = __esm({
|
|
|
10521
10559
|
}
|
|
10522
10560
|
});
|
|
10523
10561
|
|
|
10562
|
+
// src/cli/commands/repair.ts
|
|
10563
|
+
function computeRepairs(state, warnings) {
|
|
10564
|
+
const integrityWarning = warnings.find(
|
|
10565
|
+
(w) => INTEGRITY_WARNING_TYPES.includes(w.type)
|
|
10566
|
+
);
|
|
10567
|
+
if (integrityWarning) {
|
|
10568
|
+
return {
|
|
10569
|
+
fixes: [],
|
|
10570
|
+
error: `Cannot repair: data integrity issue in ${integrityWarning.file}: ${integrityWarning.message}. Fix the corrupt file first, then retry.`,
|
|
10571
|
+
tickets: [],
|
|
10572
|
+
issues: []
|
|
10573
|
+
};
|
|
10574
|
+
}
|
|
10575
|
+
const fixes = [];
|
|
10576
|
+
const modifiedTickets = [];
|
|
10577
|
+
const modifiedIssues = [];
|
|
10578
|
+
const ticketIDs = new Set(state.tickets.map((t) => t.id));
|
|
10579
|
+
const phaseIDs = new Set(state.roadmap.phases.map((p) => {
|
|
10580
|
+
const id = p.id;
|
|
10581
|
+
return typeof id === "object" && id !== null ? id.rawValue ?? String(id) : String(id);
|
|
10582
|
+
}));
|
|
10583
|
+
for (const ticket of state.tickets) {
|
|
10584
|
+
let modified = false;
|
|
10585
|
+
let blockedBy = [...ticket.blockedBy];
|
|
10586
|
+
let parentTicket = ticket.parentTicket;
|
|
10587
|
+
let phase = ticket.phase;
|
|
10588
|
+
const validBlockedBy = blockedBy.filter((ref) => ticketIDs.has(ref));
|
|
10589
|
+
if (validBlockedBy.length < blockedBy.length) {
|
|
10590
|
+
const removed = blockedBy.filter((ref) => !ticketIDs.has(ref));
|
|
10591
|
+
blockedBy = validBlockedBy;
|
|
10592
|
+
modified = true;
|
|
10593
|
+
fixes.push({ entity: ticket.id, field: "blockedBy", description: `Removed stale refs: ${removed.join(", ")}` });
|
|
10594
|
+
}
|
|
10595
|
+
if (parentTicket && !ticketIDs.has(parentTicket)) {
|
|
10596
|
+
fixes.push({ entity: ticket.id, field: "parentTicket", description: `Cleared stale ref: ${parentTicket}` });
|
|
10597
|
+
parentTicket = null;
|
|
10598
|
+
modified = true;
|
|
10599
|
+
}
|
|
10600
|
+
const phaseRaw = typeof phase === "object" && phase !== null ? phase.rawValue ?? String(phase) : phase != null ? String(phase) : null;
|
|
10601
|
+
if (phaseRaw && !phaseIDs.has(phaseRaw)) {
|
|
10602
|
+
fixes.push({ entity: ticket.id, field: "phase", description: `Cleared stale phase: ${phaseRaw}` });
|
|
10603
|
+
phase = null;
|
|
10604
|
+
modified = true;
|
|
10605
|
+
}
|
|
10606
|
+
if (modified) {
|
|
10607
|
+
modifiedTickets.push({ ...ticket, blockedBy, parentTicket, phase });
|
|
10608
|
+
}
|
|
10609
|
+
}
|
|
10610
|
+
for (const issue of state.issues) {
|
|
10611
|
+
let modified = false;
|
|
10612
|
+
let relatedTickets = [...issue.relatedTickets];
|
|
10613
|
+
let phase = issue.phase;
|
|
10614
|
+
const validRelated = relatedTickets.filter((ref) => ticketIDs.has(ref));
|
|
10615
|
+
if (validRelated.length < relatedTickets.length) {
|
|
10616
|
+
const removed = relatedTickets.filter((ref) => !ticketIDs.has(ref));
|
|
10617
|
+
relatedTickets = validRelated;
|
|
10618
|
+
modified = true;
|
|
10619
|
+
fixes.push({ entity: issue.id, field: "relatedTickets", description: `Removed stale refs: ${removed.join(", ")}` });
|
|
10620
|
+
}
|
|
10621
|
+
const issuePhaseRaw = typeof phase === "object" && phase !== null ? phase.rawValue ?? String(phase) : phase != null ? String(phase) : null;
|
|
10622
|
+
if (issuePhaseRaw && !phaseIDs.has(issuePhaseRaw)) {
|
|
10623
|
+
fixes.push({ entity: issue.id, field: "phase", description: `Cleared stale phase: ${issuePhaseRaw}` });
|
|
10624
|
+
phase = null;
|
|
10625
|
+
modified = true;
|
|
10626
|
+
}
|
|
10627
|
+
if (modified) {
|
|
10628
|
+
modifiedIssues.push({ ...issue, relatedTickets, phase });
|
|
10629
|
+
}
|
|
10630
|
+
}
|
|
10631
|
+
return { fixes, tickets: modifiedTickets, issues: modifiedIssues };
|
|
10632
|
+
}
|
|
10633
|
+
function handleRepair(ctx, dryRun) {
|
|
10634
|
+
const { fixes, error } = computeRepairs(ctx.state, ctx.warnings);
|
|
10635
|
+
if (error) {
|
|
10636
|
+
return { output: error, errorCode: "project_corrupt" };
|
|
10637
|
+
}
|
|
10638
|
+
if (fixes.length === 0) {
|
|
10639
|
+
return { output: "No stale references found. Project is clean." };
|
|
10640
|
+
}
|
|
10641
|
+
const lines = [`Found ${fixes.length} stale reference(s)${dryRun ? " (dry run)" : ""}:`, ""];
|
|
10642
|
+
for (const fix of fixes) {
|
|
10643
|
+
lines.push(`- ${fix.entity}.${fix.field}: ${fix.description}`);
|
|
10644
|
+
}
|
|
10645
|
+
if (dryRun) {
|
|
10646
|
+
lines.push("", "Run without --dry-run to apply fixes.");
|
|
10647
|
+
}
|
|
10648
|
+
return { output: lines.join("\n") };
|
|
10649
|
+
}
|
|
10650
|
+
var init_repair = __esm({
|
|
10651
|
+
"src/cli/commands/repair.ts"() {
|
|
10652
|
+
"use strict";
|
|
10653
|
+
init_esm_shims();
|
|
10654
|
+
init_errors();
|
|
10655
|
+
}
|
|
10656
|
+
});
|
|
10657
|
+
|
|
10524
10658
|
// src/cli/commands/init.ts
|
|
10525
10659
|
import { basename as basename2 } from "path";
|
|
10526
10660
|
function registerInitCommand(yargs) {
|
|
@@ -11605,6 +11739,7 @@ __export(register_exports, {
|
|
|
11605
11739
|
registerRecapCommand: () => registerRecapCommand,
|
|
11606
11740
|
registerRecommendCommand: () => registerRecommendCommand,
|
|
11607
11741
|
registerReferenceCommand: () => registerReferenceCommand,
|
|
11742
|
+
registerRepairCommand: () => registerRepairCommand,
|
|
11608
11743
|
registerSelftestCommand: () => registerSelftestCommand,
|
|
11609
11744
|
registerSessionCommand: () => registerSessionCommand,
|
|
11610
11745
|
registerSetupSkillCommand: () => registerSetupSkillCommand,
|
|
@@ -11635,6 +11770,47 @@ function registerValidateCommand(yargs) {
|
|
|
11635
11770
|
}
|
|
11636
11771
|
);
|
|
11637
11772
|
}
|
|
11773
|
+
function registerRepairCommand(yargs) {
|
|
11774
|
+
return yargs.command(
|
|
11775
|
+
"repair",
|
|
11776
|
+
"Fix stale references in .story/ data",
|
|
11777
|
+
(y) => y.option("dry-run", { type: "boolean", default: false, describe: "Show what would be fixed without writing" }),
|
|
11778
|
+
async (argv) => {
|
|
11779
|
+
const dryRun = argv["dry-run"];
|
|
11780
|
+
if (dryRun) {
|
|
11781
|
+
await runReadCommand("md", (ctx) => handleRepair(ctx, true));
|
|
11782
|
+
} else {
|
|
11783
|
+
const { withProjectLock: withProjectLock2, writeTicketUnlocked: writeTicketUnlocked2, writeIssueUnlocked: writeIssueUnlocked2, runTransactionUnlocked: runTransactionUnlocked2 } = await Promise.resolve().then(() => (init_project_loader(), project_loader_exports));
|
|
11784
|
+
const root = (await Promise.resolve().then(() => (init_project_root_discovery(), project_root_discovery_exports))).discoverProjectRoot();
|
|
11785
|
+
await withProjectLock2(root, { strict: false }, async ({ state, warnings }) => {
|
|
11786
|
+
const result = computeRepairs(state, warnings);
|
|
11787
|
+
if (result.error) {
|
|
11788
|
+
writeOutput(result.error);
|
|
11789
|
+
process.exitCode = ExitCode.USER_ERROR;
|
|
11790
|
+
return;
|
|
11791
|
+
}
|
|
11792
|
+
if (result.fixes.length === 0) {
|
|
11793
|
+
writeOutput("No stale references found. Project is clean.");
|
|
11794
|
+
return;
|
|
11795
|
+
}
|
|
11796
|
+
await runTransactionUnlocked2(root, async () => {
|
|
11797
|
+
for (const ticket of result.tickets) {
|
|
11798
|
+
await writeTicketUnlocked2(ticket, root);
|
|
11799
|
+
}
|
|
11800
|
+
for (const issue of result.issues) {
|
|
11801
|
+
await writeIssueUnlocked2(issue, root);
|
|
11802
|
+
}
|
|
11803
|
+
});
|
|
11804
|
+
const lines = [`Fixed ${result.fixes.length} stale reference(s):`, ""];
|
|
11805
|
+
for (const fix of result.fixes) {
|
|
11806
|
+
lines.push(`- ${fix.entity}.${fix.field}: ${fix.description}`);
|
|
11807
|
+
}
|
|
11808
|
+
writeOutput(lines.join("\n"));
|
|
11809
|
+
});
|
|
11810
|
+
}
|
|
11811
|
+
}
|
|
11812
|
+
);
|
|
11813
|
+
}
|
|
11638
11814
|
function registerHandoverCommand(yargs) {
|
|
11639
11815
|
return yargs.command(
|
|
11640
11816
|
"handover",
|
|
@@ -13606,6 +13782,7 @@ var init_register = __esm({
|
|
|
13606
13782
|
init_output_formatter();
|
|
13607
13783
|
init_status();
|
|
13608
13784
|
init_validate();
|
|
13785
|
+
init_repair();
|
|
13609
13786
|
init_handover();
|
|
13610
13787
|
init_blocker();
|
|
13611
13788
|
init_ticket2();
|
|
@@ -13655,9 +13832,10 @@ async function runCli() {
|
|
|
13655
13832
|
registerSetupSkillCommand: registerSetupSkillCommand2,
|
|
13656
13833
|
registerHookStatusCommand: registerHookStatusCommand2,
|
|
13657
13834
|
registerConfigCommand: registerConfigCommand2,
|
|
13658
|
-
registerSessionCommand: registerSessionCommand2
|
|
13835
|
+
registerSessionCommand: registerSessionCommand2,
|
|
13836
|
+
registerRepairCommand: registerRepairCommand2
|
|
13659
13837
|
} = await Promise.resolve().then(() => (init_register(), register_exports));
|
|
13660
|
-
const version2 = "0.1.
|
|
13838
|
+
const version2 = "0.1.35";
|
|
13661
13839
|
class HandledError extends Error {
|
|
13662
13840
|
constructor() {
|
|
13663
13841
|
super("HANDLED_ERROR");
|
|
@@ -13689,6 +13867,7 @@ async function runCli() {
|
|
|
13689
13867
|
cli = registerHandoverCommand2(cli);
|
|
13690
13868
|
cli = registerBlockerCommand2(cli);
|
|
13691
13869
|
cli = registerValidateCommand2(cli);
|
|
13870
|
+
cli = registerRepairCommand2(cli);
|
|
13692
13871
|
cli = registerSnapshotCommand2(cli);
|
|
13693
13872
|
cli = registerRecapCommand2(cli);
|
|
13694
13873
|
cli = registerExportCommand2(cli);
|
package/dist/mcp.js
CHANGED
|
@@ -2984,7 +2984,20 @@ function validateRelatedTickets(ids, state) {
|
|
|
2984
2984
|
}
|
|
2985
2985
|
}
|
|
2986
2986
|
}
|
|
2987
|
+
function buildErrorMultiset2(findings) {
|
|
2988
|
+
const counts = /* @__PURE__ */ new Map();
|
|
2989
|
+
const messages = /* @__PURE__ */ new Map();
|
|
2990
|
+
for (const f of findings) {
|
|
2991
|
+
if (f.level !== "error") continue;
|
|
2992
|
+
const key = `${f.code}|${f.entity ?? ""}|${f.message}`;
|
|
2993
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
2994
|
+
messages.set(key, f.message);
|
|
2995
|
+
}
|
|
2996
|
+
return { counts, messages };
|
|
2997
|
+
}
|
|
2987
2998
|
function validatePostWriteIssueState(candidate, state, isCreate) {
|
|
2999
|
+
const preResult = validateProject(state);
|
|
3000
|
+
const { counts: preErrors } = buildErrorMultiset2(preResult.findings);
|
|
2988
3001
|
const existingIssues = [...state.issues];
|
|
2989
3002
|
if (isCreate) {
|
|
2990
3003
|
existingIssues.push(candidate);
|
|
@@ -3001,11 +3014,17 @@ function validatePostWriteIssueState(candidate, state, isCreate) {
|
|
|
3001
3014
|
config: state.config,
|
|
3002
3015
|
handoverFilenames: [...state.handoverFilenames]
|
|
3003
3016
|
});
|
|
3004
|
-
const
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3017
|
+
const postResult = validateProject(postState);
|
|
3018
|
+
const { counts: postErrors, messages: postMessages } = buildErrorMultiset2(postResult.findings);
|
|
3019
|
+
const newErrors = [];
|
|
3020
|
+
for (const [key, postCount] of postErrors) {
|
|
3021
|
+
const preCount = preErrors.get(key) ?? 0;
|
|
3022
|
+
if (postCount > preCount) {
|
|
3023
|
+
newErrors.push(postMessages.get(key) ?? key);
|
|
3024
|
+
}
|
|
3025
|
+
}
|
|
3026
|
+
if (newErrors.length > 0) {
|
|
3027
|
+
throw new CliValidationError("validation_failed", `Write would create invalid state: ${newErrors.join("; ")}`);
|
|
3009
3028
|
}
|
|
3010
3029
|
}
|
|
3011
3030
|
async function handleIssueCreate(args, format, root) {
|
|
@@ -4205,7 +4224,20 @@ function validateParentTicket(parentId, ticketId, state) {
|
|
|
4205
4224
|
throw new CliValidationError("invalid_input", `Parent ticket ${parentId} not found`);
|
|
4206
4225
|
}
|
|
4207
4226
|
}
|
|
4227
|
+
function buildErrorMultiset(findings) {
|
|
4228
|
+
const counts = /* @__PURE__ */ new Map();
|
|
4229
|
+
const messages = /* @__PURE__ */ new Map();
|
|
4230
|
+
for (const f of findings) {
|
|
4231
|
+
if (f.level !== "error") continue;
|
|
4232
|
+
const key = `${f.code}|${f.entity ?? ""}|${f.message}`;
|
|
4233
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
4234
|
+
messages.set(key, f.message);
|
|
4235
|
+
}
|
|
4236
|
+
return { counts, messages };
|
|
4237
|
+
}
|
|
4208
4238
|
function validatePostWriteState(candidate, state, isCreate) {
|
|
4239
|
+
const preResult = validateProject(state);
|
|
4240
|
+
const { counts: preErrors } = buildErrorMultiset(preResult.findings);
|
|
4209
4241
|
const existingTickets = [...state.tickets];
|
|
4210
4242
|
if (isCreate) {
|
|
4211
4243
|
existingTickets.push(candidate);
|
|
@@ -4222,11 +4254,17 @@ function validatePostWriteState(candidate, state, isCreate) {
|
|
|
4222
4254
|
config: state.config,
|
|
4223
4255
|
handoverFilenames: [...state.handoverFilenames]
|
|
4224
4256
|
});
|
|
4225
|
-
const
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4257
|
+
const postResult = validateProject(postState);
|
|
4258
|
+
const { counts: postErrors, messages: postMessages } = buildErrorMultiset(postResult.findings);
|
|
4259
|
+
const newErrors = [];
|
|
4260
|
+
for (const [key, postCount] of postErrors) {
|
|
4261
|
+
const preCount = preErrors.get(key) ?? 0;
|
|
4262
|
+
if (postCount > preCount) {
|
|
4263
|
+
newErrors.push(postMessages.get(key) ?? key);
|
|
4264
|
+
}
|
|
4265
|
+
}
|
|
4266
|
+
if (newErrors.length > 0) {
|
|
4267
|
+
throw new CliValidationError("validation_failed", `Write would create invalid state: ${newErrors.join("; ")}`);
|
|
4230
4268
|
}
|
|
4231
4269
|
}
|
|
4232
4270
|
async function handleTicketCreate(args, format, root) {
|
|
@@ -9521,7 +9559,7 @@ async function ensureGitignoreEntries(gitignorePath, entries) {
|
|
|
9521
9559
|
// src/mcp/index.ts
|
|
9522
9560
|
var ENV_VAR2 = "CLAUDESTORY_PROJECT_ROOT";
|
|
9523
9561
|
var CONFIG_PATH2 = ".story/config.json";
|
|
9524
|
-
var version = "0.1.
|
|
9562
|
+
var version = "0.1.35";
|
|
9525
9563
|
function tryDiscoverRoot() {
|
|
9526
9564
|
const envRoot = process.env[ENV_VAR2];
|
|
9527
9565
|
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.35",
|
|
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": [
|