slopwaresystems 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +172 -145
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -26478,7 +26478,7 @@ var TaskEventRecord = external_exports.object({
26478
26478
 
26479
26479
  // ../contract/src/work/sessions.ts
26480
26480
  var AgentHarness = external_exports.enum(["claude", "codex", "cursor", "other"]);
26481
- var WORKERS_PER_SESSION = 8;
26481
+ var WORKERS_PER_SESSION = 200;
26482
26482
  var WORKER_LABEL_MAX = 80;
26483
26483
  var DOING_MAX = 120;
26484
26484
  var SessionWorker = external_exports.object({
@@ -26490,6 +26490,13 @@ var SessionWorker = external_exports.object({
26490
26490
  doing: external_exports.string().trim().max(DOING_MAX).nullable().default(null),
26491
26491
  since: Timestamp
26492
26492
  });
26493
+ var SessionWorkerEntry = SessionWorker.omit({ doing: true });
26494
+ var SessionWorkerLine = external_exports.object({ ref: SessionWorker.shape.ref, doing: SessionWorker.shape.doing });
26495
+ var SessionRoster = external_exports.object({ workers: external_exports.array(SessionWorkerEntry).max(WORKERS_PER_SESSION) });
26496
+ var SessionDoing = external_exports.object({
26497
+ doing: external_exports.string().trim().max(DOING_MAX).nullable().default(null),
26498
+ lines: external_exports.array(SessionWorkerLine).max(WORKERS_PER_SESSION).default([])
26499
+ });
26493
26500
  var SessionActivity = external_exports.object({
26494
26501
  doing: external_exports.string().trim().max(DOING_MAX).nullable().default(null),
26495
26502
  workers: external_exports.array(SessionWorker).max(WORKERS_PER_SESSION).default([])
@@ -26543,12 +26550,18 @@ var SessionPush = external_exports.discriminatedUnion("type", [
26543
26550
  external_exports.object({ type: external_exports.literal("reachable"), on: external_exports.boolean() }),
26544
26551
  /** Whether anyone is looking at this project's board. Off, an agent stops saying what it is doing. */
26545
26552
  external_exports.object({ type: external_exports.literal("watched"), on: external_exports.boolean() }),
26546
- /** To board watchers: what one agent and its workers are doing now. Carries its own payload; nothing to refetch. */
26547
- SessionActivity.extend({ type: external_exports.literal("activity"), session: Id }),
26553
+ /** To board watchers: one agent's workers now, replacing the ones before. Carries its own payload; nothing to refetch. */
26554
+ SessionRoster.extend({ type: external_exports.literal("workers"), session: Id }),
26555
+ /** To board watchers: what one agent is doing now, and the lines of its workers that changed. Nothing to refetch. */
26556
+ SessionDoing.extend({ type: external_exports.literal("doing"), session: Id }),
26548
26557
  /** To board watchers: something in the project changed; refetch. */
26549
26558
  external_exports.object({ type: external_exports.literal("changed"), scope: external_exports.string() })
26550
26559
  ]);
26551
- var SessionUp = external_exports.discriminatedUnion("type", [SessionActivity.extend({ type: external_exports.literal("activity") })]);
26560
+ var SessionUp = external_exports.discriminatedUnion("type", [
26561
+ SessionRoster.extend({ type: external_exports.literal("workers") }),
26562
+ SessionDoing.extend({ type: external_exports.literal("doing") }),
26563
+ SessionActivity.extend({ type: external_exports.literal("activity") })
26564
+ ]);
26552
26565
  var SessionMessagesInput = external_exports.object({ cursor: external_exports.coerce.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional() });
26553
26566
  var SessionMessages = external_exports.object({
26554
26567
  cursor: external_exports.number().int().nonnegative(),
@@ -26567,7 +26580,7 @@ var AGENT_NAMES = [
26567
26580
  "Doug, Just Doug",
26568
26581
  "Admiral Crumb",
26569
26582
  "Lord Fluffington III",
26570
- "Meatball Descartes",
26583
+ "Bertram Puddle",
26571
26584
  "Gerald Spaghetti",
26572
26585
  "Mildred Danger",
26573
26586
  "Chunky Bartholomew",
@@ -26577,10 +26590,10 @@ var AGENT_NAMES = [
26577
26590
  "Susan the Unyielding",
26578
26591
  "Gravy Boat",
26579
26592
  "Trevor Cabbage",
26580
- "Dame Judi Bench",
26593
+ "Colonel Custardson",
26581
26594
  "Mr. Business Casual",
26582
- "Toast Malone",
26583
- "Gandalf the Beige",
26595
+ "Mabel Hoopla",
26596
+ "Sir Humphrey Dribble",
26584
26597
  "Terrence Moist",
26585
26598
  "Professor Pants",
26586
26599
  "Lil Bureaucrat",
@@ -26589,53 +26602,53 @@ var AGENT_NAMES = [
26589
26602
  "Ol' Dependable",
26590
26603
  "Kevin But Louder",
26591
26604
  "Nigel Overthink",
26592
- "Sausage Aristotle",
26605
+ "Lady Crumpetshire",
26593
26606
  "The Honorable Blorp",
26594
26607
  "Greg of the Marsh",
26595
- "Karen Kraken",
26608
+ "Horatio Noodle",
26596
26609
  "Bingus Prime",
26597
26610
  "Steve Two Hats",
26598
26611
  "Margaret Doom",
26599
26612
  "Ranch Dressing Rick",
26600
26613
  "Sir Naps-a-Lot",
26601
- "Cheddar Van Halen",
26614
+ "Gladys Thunderbun",
26602
26615
  "Barb Dwyer",
26603
26616
  "Deputy Croissant",
26604
26617
  "Linda Explosion",
26605
- "Humphrey Bogus",
26618
+ "Rupert Soggybiscuit",
26606
26619
  "Tuna Wellington",
26607
26620
  "Big Mistake Mike",
26608
26621
  "Quentin Quinoa",
26609
- "Dolores Umbrage",
26622
+ "Nora Nonsense",
26610
26623
  "Fancy Larry",
26611
26624
  "Norman Conquest",
26612
26625
  "Beatrice Bagpipe",
26613
26626
  "Chad the Apologetic",
26614
26627
  "Wanda Whiplash",
26615
- "Alan Turingpoint",
26616
- "Mango Unchained",
26628
+ "Baxter Fiddlesticks",
26629
+ "Philippa Fluster",
26617
26630
  "Dwight Lightly",
26618
- "Brisket Newton",
26631
+ "Edna Pickleworth",
26619
26632
  "Ferris Wheeler",
26620
26633
  "Peggy Sue Me",
26621
26634
  "Hank Dilemma",
26622
- "Vlad the Inhaler",
26623
- "Bagel Bardot",
26624
- "Clive Staples",
26635
+ "Morris Doodah",
26636
+ "Primrose Kerplunk",
26637
+ "Oswin Dithers",
26625
26638
  "Ignatius Pudding",
26626
- "Pancake Lafayette",
26639
+ "Hattie Hullabaloo",
26627
26640
  "Rhonda Voo",
26628
26641
  "Mort Gage",
26629
26642
  "Sheila Crumpet",
26630
26643
  "Dennis Existential",
26631
26644
  "Justin Case",
26632
26645
  "Barry Cuda",
26633
- "Lil Pomp",
26634
- "Winston Churchmouse",
26646
+ "Basil Brouhaha",
26647
+ "Lavinia Pottersnap",
26635
26648
  "Petunia Blastoff",
26636
- "Bob Ross Cosplayer",
26637
- "Cornelius Fudge Sr.",
26638
- "Otis Redundant",
26649
+ "Crispin Wafflethorpe",
26650
+ "Imogen Bumbershoot",
26651
+ "Ptolemy Squelch",
26639
26652
  "Brad Wurst",
26640
26653
  "Dr. Feelgoodish",
26641
26654
  "Grandpa Wifi",
@@ -26643,28 +26656,28 @@ var AGENT_NAMES = [
26643
26656
  "Marge Inal",
26644
26657
  "Chip Monk",
26645
26658
  "Polly Estera",
26646
- "Gustavo Fringe",
26647
- "Dale Gribbling",
26648
- "Abe Froman Jr.",
26659
+ "Daphne Doodle",
26660
+ "Montague Muffin",
26661
+ "Rosamund Fizzwick",
26649
26662
  "Noodle Kowalski",
26650
26663
  "Debbie Downloader",
26651
- "Frank Lloyd Wrong",
26652
- "Tammy Fay Baker",
26664
+ "Wilfred Kettleblack",
26665
+ "Ottoline Plonk",
26653
26666
  "Yolanda Bolognese",
26654
- "Pierre Delecto",
26667
+ "Jasper Snickerdoodle",
26655
26668
  "Kevin, Reluctantly",
26656
- "Butterscotch Vance",
26669
+ "Mirabel Flapjack",
26657
26670
  "Reginald Sandwich",
26658
26671
  "Cliff Hanger",
26659
- "Elmo Deodorant",
26672
+ "Fenwick Grumbleton",
26660
26673
  "Skip Intro",
26661
26674
  "Barnaby Crunch",
26662
26675
  "Petra Fied",
26663
26676
  "Sir Wigglesworth",
26664
26677
  "Glenda Quench",
26665
- "Rusty Shackleford Jr.",
26678
+ "Ethelred Tinpot",
26666
26679
  "Ophelia Blip",
26667
- "Duke Nuke'em Lite",
26680
+ "Opal Snorkel",
26668
26681
  "Bertha Von Snooze",
26669
26682
  "Tobias Flibbert",
26670
26683
  "Nan Bread",
@@ -26672,78 +26685,78 @@ var AGENT_NAMES = [
26672
26685
  "Muffin Dunbar",
26673
26686
  "Percival Wetsock",
26674
26687
  "Agnes Thunderpants",
26675
- "Colin Firthday",
26688
+ "Rufus Porridge",
26676
26689
  "Lettuce Prey",
26677
26690
  "Jimbo Sequitur",
26678
- "Doris Skywalker",
26691
+ "Tabitha Tumbleweed",
26679
26692
  "Brock Lee",
26680
- "Fig Newton-John",
26693
+ "Algernon Splat",
26681
26694
  "Hal Ape\xF1o",
26682
- "Ivana Tinkle",
26683
- "Kenny Loggins Off",
26695
+ "Marigold Mayhem",
26696
+ "Lionel Lumpkin",
26684
26697
  "Lola Granola",
26685
26698
  "Max Volume",
26686
26699
  "Nacho Average Agent",
26687
- "Olaf Lundgren",
26700
+ "Constance Kerfuffle",
26688
26701
  "Pat Downe",
26689
26702
  "Quincy Meh",
26690
- "Ramona Flowerpot",
26691
- "Salami Davis Jr.",
26703
+ "Desmond Dawdle",
26704
+ "Beryl Bumblebrook",
26692
26705
  "Terry Aki",
26693
26706
  "Ursula Mildew",
26694
26707
  "Vinnie Vidi Vici",
26695
26708
  "Wendy Windbreaker",
26696
- "Xander Cage-Free",
26709
+ "Humphrey Wafflestomp",
26697
26710
  "Yvonne Yawn",
26698
26711
  "Zeke Squeak",
26699
26712
  "Ambrose Mumble",
26700
26713
  "Bunny Rebellion",
26701
- "Clancy Wiggum Lite",
26714
+ "Nettie Nincompoop",
26702
26715
  "Delilah Dumpling",
26703
26716
  "Egbert Sideways",
26704
26717
  "Fiona Fondue",
26705
26718
  "Gunther Gumshoe",
26706
26719
  "Hortense Haggle",
26707
26720
  "Igor Beaver",
26708
- "Jolene Jolene",
26709
- "Kirby Vacuum",
26710
- "Lars Farquaad",
26721
+ "Sir Bartleby Blunder",
26722
+ "Cecil Crinkle",
26723
+ "Dorothea Dollop",
26711
26724
  "Mavis Meander",
26712
- "Ned Flanders Field",
26725
+ "Magnus Mopp",
26713
26726
  "Octavia Oops",
26714
26727
  "Pippa Puddlejump",
26715
26728
  "Quigley Quagmire",
26716
26729
  "Roland Butter",
26717
26730
  "Sophie Sofa",
26718
26731
  "Thaddeus Thicc",
26719
- "Ulysses Grunt",
26732
+ "Pearl Plinkett",
26720
26733
  "Valerie Vibe",
26721
- "Waldo Found",
26722
- "Xenia Warrior Princess",
26734
+ "Silas Sprocket",
26735
+ "Violet Vexington",
26723
26736
  "Yusuf Yikes",
26724
- "Zsa Zsa Gabortion",
26737
+ "Gilbert Gubbins",
26725
26738
  "Archibald Shrimp",
26726
26739
  "Bianca Bellows",
26727
26740
  "Cornbread Stanley",
26728
26741
  "Dot Matrix",
26729
- "Eugene Levy Jr.",
26742
+ "Hester Hobnob",
26730
26743
  "Fanny Pack",
26731
- "Gordon Ramsgate",
26744
+ "Lysander Lollop",
26732
26745
  "Hilda Honk",
26733
- "Inigo Montoya II",
26734
- "Jarvis Cocker Spaniel",
26735
- "Kermit Crumb",
26746
+ "Minerva Mothball",
26747
+ "Neville Nudge",
26748
+ "Odette Oddsock",
26736
26749
  "Lupita Lint",
26737
26750
  "Morty Fied",
26738
- "Nelly Furtado Jr.",
26751
+ "Percy Pumpernickel",
26739
26752
  "Ozzy Oatmeal",
26740
26753
  "Prudence Prune",
26741
- "Quaid Damage",
26742
- "Randy Marsh Gas",
26743
- "Sigmund Freud Slip",
26754
+ "Rowena Rumpus",
26755
+ "Seymour Snoozeworth",
26756
+ "Thelma Tiddlywink",
26744
26757
  "Tallulah Tumble",
26745
- "Umberto Echo",
26746
- "Velma Dinkley Jr.",
26758
+ "Vernon Vroom",
26759
+ "Wendell Whimsy",
26747
26760
  "Wilbur Wobbleton",
26748
26761
  "Ximena Xylophone",
26749
26762
  "Yannick Yodel",
@@ -26752,89 +26765,89 @@ var AGENT_NAMES = [
26752
26765
  "Beulah Bumble",
26753
26766
  "Chauncey Chowder",
26754
26767
  "Darla Drizzle",
26755
- "Enid Blight",
26768
+ "Yvette Yonder",
26756
26769
  "Fergus Fumble",
26757
26770
  "Gretchen Grumble",
26758
26771
  "Horace Hush",
26759
26772
  "Ivy Overgrown",
26760
- "Jethro Tulle",
26773
+ "Zachariah Zoom",
26761
26774
  "Kiki Kibble",
26762
- "Leonard Nimoy Jr.",
26763
- "Maude Flanders Field",
26775
+ "Admiral Biscuit",
26776
+ "Baron Von Doily",
26764
26777
  "Norbert Nibble",
26765
- "Orville Reddenbacher",
26778
+ "Captain Kettle",
26766
26779
  "Phyllis Phlegm",
26767
- "Quentin Tarantino Jr.",
26780
+ "Duchess of Dustbunny",
26768
26781
  "Roxie Rasp",
26769
- "Stanley Kubrick Jr.",
26770
- "Tiffany Aching",
26782
+ "Earl of Earmuffs",
26783
+ "Commodore Crouton",
26771
26784
  "Ulrich Unwell",
26772
- "Vera Wang Chung",
26773
- "Wallace Gromit Jr.",
26785
+ "Madame Mishap",
26786
+ "Professor Fidget",
26774
26787
  "Xavier Xerox",
26775
- "Yolo Swaggins",
26776
- "Zelda Fitzgerald II",
26788
+ "Sergeant Snuggles",
26789
+ "Viscount Vinaigrette",
26777
26790
  "Alfie Wafflehouse",
26778
- "Bea Arthur Fonzarelli",
26779
- "Cyril Sneer",
26780
- "Dudley Doo-Wrong",
26791
+ "Auntie Avalanche",
26792
+ "Uncle Umbrella",
26793
+ "Doctor Doodad",
26781
26794
  "Esther Bunny",
26782
26795
  "Flossie Floss",
26783
26796
  "Gustav Gravlax",
26784
26797
  "Henrietta Hiccup",
26785
- "Isaac Newton Jr.",
26786
- "Judy Jetsonstream",
26798
+ "Brigadier Bagel",
26799
+ "Marquis de Mustard",
26787
26800
  "Kelvin Degree",
26788
- "Lionel Ritchie Rich",
26789
- "Mortimer Snerd",
26790
- "Nigella Lawsuit",
26791
- "Oprah Winfreeze",
26792
- "Pablo Escobar Jr.",
26801
+ "Lady Lumpington",
26802
+ "Sir Squeaksalot",
26803
+ "Grumpy Gregor",
26804
+ "Moody Maureen",
26805
+ "Sleepy Siegfried",
26793
26806
  "Queenie Quibble",
26794
- "Rodney Dangerfield Jr.",
26795
- "Sabrina Teenage Witch",
26807
+ "Noisy Norris",
26808
+ "Wobbly Walter",
26796
26809
  "Toby Ornot Toby",
26797
26810
  "Ulla Bora",
26798
- "Vince Vaughn Jr.",
26799
- "Winona Rider Jr.",
26811
+ "Tiny Theodore",
26812
+ "Barnacle Beatrix",
26800
26813
  "Xerxes Xanthum",
26801
- "Yoda Lay-He-Hoo",
26802
- "Zachary Binx",
26803
- "Aloysius Snuffleupagus",
26804
- "Barbara Streisandwich",
26805
- "Chester Copperpot",
26814
+ "Crumbly Cedric",
26815
+ "Fudge McGee",
26816
+ "Pickles O'Malley",
26817
+ "Waffles McGraw",
26818
+ "Biscuit Bramblebee",
26806
26819
  "Deirdre Dither",
26807
- "Ebenezer Screwed",
26820
+ "Dumpling Duffy",
26808
26821
  "Fitzgerald Fizzle",
26809
26822
  "Gwendolyn Gnash",
26810
- "Humbert Humbug",
26823
+ "Parsnip Pemberton",
26811
26824
  "Isadora Drizzle",
26812
- "Jebediah Springfield",
26813
- "Kunta Kinte Jr.",
26825
+ "Turnip Tattersall",
26826
+ "Radish Ridgeway",
26814
26827
  "Lucinda Lozenge",
26815
- "Montgomery Burns Unit",
26816
- "Nadia Comaneci Jr.",
26817
- "Oswald Cobblepot",
26828
+ "Gherkin Galloway",
26829
+ "Kipper Kensington",
26830
+ "Meringue Mulberry",
26818
26831
  "Persephone Pickle",
26819
- "Quasimodo Junior",
26832
+ "Sprout Sterling",
26820
26833
  "Rosalind Rumple",
26821
- "Sylvester Stallion",
26834
+ "Scone Spalding",
26822
26835
  "Theodora Thimble",
26823
26836
  "Umberto Unpaid",
26824
26837
  "Vivienne Vacuum",
26825
- "Wolfgang Puck Off",
26838
+ "Trifle Thistlewood",
26826
26839
  "Xena Xtra",
26827
- "Yakov Smirnoff Jr.",
26840
+ "Nutmeg Nottingham",
26828
26841
  "Zinnia Zipper",
26829
- "Alistair Cookie",
26842
+ "Pudding Pembleton",
26830
26843
  "Belinda Bilge",
26831
26844
  "Cuthbert Custard",
26832
26845
  "Dorcas Doorknob",
26833
26846
  "Ezekiel Zucchini",
26834
- "Florence Nightingale Jr.",
26847
+ "Crumpet Carmichael",
26835
26848
  "Gideon Gizzard",
26836
26849
  "Harriet Hairball",
26837
- "Irving Berlin Wall",
26850
+ "Walnut Whitlock",
26838
26851
  "Jocasta Jam",
26839
26852
  "Kingsley Kipper",
26840
26853
  "Leopold Loophole",
@@ -26846,17 +26859,17 @@ var AGENT_NAMES = [
26846
26859
  "Reuben Sandwich",
26847
26860
  "Saoirse Sneeze",
26848
26861
  "Tobias Tofu",
26849
- "Ulysses S. Grunt",
26862
+ "Teacup Tremaine",
26850
26863
  "Veronica Vex",
26851
26864
  "Wilhelmina Wombat",
26852
26865
  "Xiomara Xmas",
26853
- "Yorick Alas",
26866
+ "Gumdrop Goodwin",
26854
26867
  "Zebulon Zest",
26855
26868
  "Ambrosia Salad",
26856
26869
  "Balthazar Bidet",
26857
26870
  "Clementine Clatter",
26858
26871
  "Dmitri Dumpling",
26859
- "Eleanor Rigby Jr.",
26872
+ "Marzipan Mortimer",
26860
26873
  "Ferdinand Fedora"
26861
26874
  ];
26862
26875
  function hashKey(key) {
@@ -29141,8 +29154,6 @@ var HeldSession = class {
29141
29154
  delivered = /* @__PURE__ */ new Set();
29142
29155
  /** A Worker older than this CLI refuses what it does not know. One refusal is enough: stop saying it. */
29143
29156
  upstreamRefused = false;
29144
- /** Whether this socket has been told anything about what the agent is doing; a new socket knows nothing again. */
29145
- toldThisSocket = false;
29146
29157
  identity;
29147
29158
  session = null;
29148
29159
  /**
@@ -29205,7 +29216,6 @@ var HeldSession = class {
29205
29216
  return;
29206
29217
  }
29207
29218
  greeted = true;
29208
- this.toldThisSocket = false;
29209
29219
  this.api.sessionId = push.session.id;
29210
29220
  this.session = push.session;
29211
29221
  this.taskKey = push.session.taskKey;
@@ -29288,16 +29298,16 @@ var HeldSession = class {
29288
29298
  }
29289
29299
  }
29290
29300
  /**
29291
- * Says what this agent and its workers are doing. Dropped when the socket is not up: the room holds only what is
29292
- * true now, and the next report follows the reconnect. The only thing this client ever sends but a ping.
29301
+ * Says who this agent's workers are, or what it and they are doing. Dropped when the socket is not up: the room
29302
+ * holds only what is true now, and the reporter says it all again after the next hello. The reporter says only what
29303
+ * changed, so an agent with no subagents that nobody is watching sends nothing at all, which is most agents most of
29304
+ * the time. The only thing this client ever sends but a ping.
29293
29305
  */
29294
- reportActivity(activity) {
29306
+ reportActivity(message) {
29295
29307
  const socket = this.socket;
29296
29308
  if (this.stopped || this.upstreamRefused || !this.session || !socket || socket.readyState !== WebSocket.OPEN) return;
29297
- if (!this.toldThisSocket && activity.doing === null && activity.workers.length === 0) return;
29298
29309
  try {
29299
- socket.send(JSON.stringify({ type: "activity", ...activity }));
29300
- this.toldThisSocket = true;
29310
+ socket.send(JSON.stringify(message));
29301
29311
  } catch {
29302
29312
  }
29303
29313
  }
@@ -29687,7 +29697,10 @@ var HarnessActivity = class {
29687
29697
  watched = false;
29688
29698
  discoveredAt = 0;
29689
29699
  timer = null;
29690
- reported = "";
29700
+ /** What the room knows: the roster it was last told, what this agent is doing, and each worker's line. */
29701
+ toldRoster = "[]";
29702
+ toldDoing = null;
29703
+ toldLines = /* @__PURE__ */ new Map();
29691
29704
  stopped = false;
29692
29705
  start() {
29693
29706
  if (this.timer || this.stopped) return;
@@ -29702,9 +29715,11 @@ var HarnessActivity = class {
29702
29715
  if (on) this.doing = null;
29703
29716
  this.tick();
29704
29717
  }
29705
- /** Say it again: the room forgets a session's activity when its socket drops, and only the agent can refill it. */
29718
+ /** Say it again: a new socket starts knowing nothing, and only the agent can refill it. */
29706
29719
  repeat() {
29707
- this.reported = "";
29720
+ this.toldRoster = "[]";
29721
+ this.toldDoing = null;
29722
+ this.toldLines.clear();
29708
29723
  this.tick();
29709
29724
  }
29710
29725
  stop() {
@@ -29726,11 +29741,20 @@ var HarnessActivity = class {
29726
29741
  } catch {
29727
29742
  }
29728
29743
  }
29729
- const activity = this.build();
29730
- const said = JSON.stringify(activity);
29731
- if (said === this.reported) return;
29732
- this.reported = said;
29733
- this.onReport(activity);
29744
+ const roster = this.buildRoster();
29745
+ const said = JSON.stringify(roster);
29746
+ if (said !== this.toldRoster) {
29747
+ this.toldRoster = said;
29748
+ const refs = new Set(roster.map((worker) => worker.ref));
29749
+ for (const ref of [...this.toldLines.keys()]) if (!refs.has(ref)) this.toldLines.delete(ref);
29750
+ this.onReport({ type: "workers", workers: roster });
29751
+ }
29752
+ const doing = this.watched ? this.doing : null;
29753
+ const changed = this.buildWorkerLines(roster, now).filter((line) => (this.toldLines.get(line.ref) ?? null) !== line.doing);
29754
+ if (changed.length === 0 && doing === this.toldDoing) return;
29755
+ this.toldDoing = doing;
29756
+ for (const line of changed) this.toldLines.set(line.ref, line.doing);
29757
+ this.onReport({ type: "doing", doing, lines: changed });
29734
29758
  }
29735
29759
  /** Which files to read: this chat's own, and one per worker still working. */
29736
29760
  discover(now) {
@@ -29772,10 +29796,19 @@ var HarnessActivity = class {
29772
29796
  }
29773
29797
  for (const worker of this.workers.values()) worker.doing = findNewestCall(worker.tail) ?? worker.doing;
29774
29798
  }
29775
- build() {
29776
- const now = Date.now();
29777
- const workers = [...this.workers.values()].sort((a, b) => b.changedAt - a.changedAt).slice(0, WORKERS_PER_SESSION).map((worker) => ({ ref: worker.ref, label: worker.label, directory: worker.directory, branch: worker.branch, doing: this.watched && now - worker.changedAt < WORKER_FRESH_MS ? worker.doing : null, since: worker.since }));
29778
- return { doing: this.watched ? this.doing : null, workers };
29799
+ /**
29800
+ * Every worker, oldest first, so the roster changes only when one starts or finishes and never because one got
29801
+ * busy. The contract's guard is far past what a harness runs; past it, the oldest are the ones listed.
29802
+ */
29803
+ buildRoster() {
29804
+ return [...this.workers.values()].sort((a, b) => a.since.localeCompare(b.since) || a.ref.localeCompare(b.ref)).slice(0, WORKERS_PER_SESSION).map((worker) => ({ ref: worker.ref, label: worker.label, directory: worker.directory, branch: worker.branch, since: worker.since }));
29805
+ }
29806
+ /** Quiet for a while: still listed, because it is probably thinking, but saying nothing about what it is doing. */
29807
+ buildWorkerLines(roster, now) {
29808
+ return roster.map(({ ref }) => {
29809
+ const worker = this.workers.get(ref);
29810
+ return { ref, doing: this.watched && now - worker.changedAt < WORKER_FRESH_MS ? worker.doing : null };
29811
+ });
29779
29812
  }
29780
29813
  };
29781
29814
 
@@ -31088,11 +31121,7 @@ function createProjectTools(api, project, identity) {
31088
31121
  const requireOwnSession = () => {
31089
31122
  if (!canHoldOwnSession()) throw new Error(SPAWNED_BY_ANOTHER_AGENT);
31090
31123
  };
31091
- let told = null;
31092
- const activity = new HarnessActivity({ id: identity.conversation, harness: identity.harness }, (report) => {
31093
- told = report;
31094
- held?.reportActivity(report);
31095
- });
31124
+ const activity = new HarnessActivity({ id: identity.conversation, harness: identity.harness }, (report) => held?.reportActivity(report));
31096
31125
  let waking = false;
31097
31126
  const wakeOwnHarness = () => {
31098
31127
  if (waking || stopped) return;
@@ -31126,10 +31155,8 @@ function createProjectTools(api, project, identity) {
31126
31155
  onMessage: wakeOwnHarness,
31127
31156
  claim: resolveOwnAgentIdentity,
31128
31157
  onReconnect: () => recovery.sync(),
31129
- // The room forgets a session's activity when its socket goes: whatever was true is said again on the new one.
31130
- onHello: () => {
31131
- if (told) held?.reportActivity(told);
31132
- },
31158
+ // A new socket starts knowing nothing about the workers: whatever is true is said again on it.
31159
+ onHello: () => activity.repeat(),
31133
31160
  onWatched: (on) => activity.setWatched(on)
31134
31161
  });
31135
31162
  activity.start();
@@ -32259,7 +32286,7 @@ async function trustCodexHooks(codexHome) {
32259
32286
  const sendNotification = (method, params) => server.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", method, params })}
32260
32287
  `);
32261
32288
  try {
32262
- await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.5.0" }, capabilities: { experimentalApi: true } });
32289
+ await callCodexMethod("initialize", { clientInfo: { name: "slop", version: "0.6.1" }, capabilities: { experimentalApi: true } });
32263
32290
  sendNotification("initialized", {});
32264
32291
  const listed = await callCodexMethod("hooks/list", { cwds: [process.cwd()] });
32265
32292
  const ours = listed.data.flatMap((entry) => entry.hooks).filter((hook) => hook.command?.startsWith("slop hook "));
@@ -32460,7 +32487,7 @@ ${written.map((path3) => ` ${path3}`).join("\n")}`);
32460
32487
  var args = process.argv.slice(2);
32461
32488
  var optionEnd = args.indexOf("--");
32462
32489
  updateJsonMode((optionEnd < 0 ? args : args.slice(0, optionEnd)).includes("--json"));
32463
- var program2 = new Command().name("slop").description("Slopware Tasks from the terminal. Everything a person can do on the board, an agent can do here.").version("0.5.0").option("--json", "machine-readable output: JSON on stdout, errors as JSON on stderr").configureOutput({
32490
+ var program2 = new Command().name("slop").description("Slopware Tasks from the terminal. Everything a person can do on the board, an agent can do here.").version("0.6.1").option("--json", "machine-readable output: JSON on stdout, errors as JSON on stderr").configureOutput({
32464
32491
  outputError: (message, write) => {
32465
32492
  if (!isJsonMode()) write(message);
32466
32493
  },
@@ -32476,7 +32503,7 @@ var taskCommand = registerTaskCommands(program2);
32476
32503
  var sessionCommand = registerSessionCommands(program2);
32477
32504
  registerThreadCommands(program2, taskCommand);
32478
32505
  registerOperationCommands(program2, taskCommand, sessionCommand);
32479
- registerMcpCommands(program2, "0.5.0");
32506
+ registerMcpCommands(program2, "0.6.1");
32480
32507
  registerGuideCommand(program2);
32481
32508
  registerSkillCommands(program2);
32482
32509
  program2.parseAsync().catch(exitWithError);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slopwaresystems",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "private": false,
5
5
  "description": "slop: the Slopware Tasks board from the terminal, for people and coding agents.",
6
6
  "type": "module",