castle-web-cli 0.4.34 → 0.4.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.
@@ -36,6 +36,7 @@ comma-separated titles or ids of the finished tasks
36
36
  \`\`\`
37
37
 
38
38
  - NEVER check a task off on your own judgment -- only a clear user statement that it works (or an explicit ask to clear it) counts. When in doubt, leave the row on the board.
39
+ - The background-tasks list below IS the board the user sees -- every row, with its id. To clear the WHOLE board at once (e.g. "clear all the tasks"), use \`all\` instead of listing ids: a \`castle-done\` with body \`all\` checks off every finished row, and a \`castle-stop\` with body \`all\` stops everything still running. Never claim the board is cleared without actually emitting the fence.
39
40
  - To STOP tasks (running or waiting) when the user asks or their work is clearly no longer wanted, include:
40
41
 
41
42
  \`\`\`castle-stop
package/dist/agent.js CHANGED
@@ -602,16 +602,31 @@ function createTaskStore(opts) {
602
602
  }
603
603
  }
604
604
  }
605
- // The router checks finished tasks off by title or id (castle-done fence).
605
+ // True when a fence body is the special token "all" / "*" (clear/stop
606
+ // everything, no per-task enumeration).
607
+ function meansAll(tokens) {
608
+ return tokens.some((t) => t.toLowerCase() === 'all' || t === '*');
609
+ }
610
+ // The router checks finished tasks off by title or id (castle-done fence),
611
+ // or "all" to clear every finished row off the board at once.
606
612
  function checkOff(tokens) {
607
- for (const id of resolveDeps(tasks, tokens))
613
+ const ids = meansAll(tokens)
614
+ ? [...tasks.values()].filter((t) => isTerminal(t.status) && !t.acknowledged).map((t) => t.id)
615
+ : resolveDeps(tasks, tokens);
616
+ for (const id of ids)
608
617
  acknowledge(id, false);
609
618
  }
610
- // The router stops tasks by title or id (castle-stop fence). Waiting tasks
611
- // are cancelled outright; running ones get their agent process killed and
612
- // finalize as interrupted via the stopRequested path.
619
+ // The router stops tasks by title or id (castle-stop fence), or "all" to
620
+ // stop everything still active. Waiting tasks are cancelled outright;
621
+ // running ones get their agent process killed and finalize as interrupted
622
+ // via the stopRequested path.
613
623
  function stop(tokens) {
614
- for (const id of resolveDeps(tasks, tokens)) {
624
+ const ids = meansAll(tokens)
625
+ ? [...tasks.values()]
626
+ .filter((t) => t.status === 'running' || t.status === 'waiting')
627
+ .map((t) => t.id)
628
+ : resolveDeps(tasks, tokens);
629
+ for (const id of ids) {
615
630
  const task = tasks.get(id);
616
631
  if (!task)
617
632
  continue;
@@ -764,7 +779,10 @@ function runRouterTurnIn(ctx, instruction) {
764
779
  messages: ctx.log.messages
765
780
  .filter((m) => m.role !== 'log' && m.id !== message.id && m.status !== 'streaming')
766
781
  .map((m) => ({ role: m.role, text: m.text })),
767
- tasks: ctx.taskStore.sorted().map(asPromptTask),
782
+ // Only the live board (unacknowledged tasks) -- match what the user sees.
783
+ // Showing every already-cleared task confused the router about what was
784
+ // actually on the board to clear / act on.
785
+ tasks: ctx.taskStore.sorted().filter((t) => !t.acknowledged).map(asPromptTask),
768
786
  instruction,
769
787
  });
770
788
  const backend = ctx.backend();
@@ -127,6 +127,7 @@ function buildFileTree(paths) {
127
127
  }
128
128
  }
129
129
  pruneChildMaps(root);
130
+ sortRootChildren(root);
130
131
  return root;
131
132
  }
132
133
  function pruneChildMaps(node) {
@@ -134,6 +135,17 @@ function pruneChildMaps(node) {
134
135
  for (const child of node.children) pruneChildMaps(child);
135
136
  delete node.childMap;
136
137
  }
138
+ // Top-level folders list in a fixed order: drawings, then scenes, then
139
+ // behaviors, then anything else alphabetically.
140
+ function sortRootChildren(root) {
141
+ const rank = (name) => {
142
+ if (name === 'drawings') return 0;
143
+ if (name === 'scenes') return 1;
144
+ if (name === 'behaviors') return 2;
145
+ return 3;
146
+ };
147
+ root.children.sort((a, b) => rank(a.name) - rank(b.name) || a.name.localeCompare(b.name));
148
+ }
137
149
  function collectDirectoryPaths(node) {
138
150
  if (node.type !== 'directory') return [];
139
151
  return [
@@ -44,6 +44,15 @@
44
44
  box-sizing: border-box;
45
45
  }
46
46
 
47
+ /* Hide scrollbars across the whole editor while keeping scroll functional. */
48
+ :global(*) {
49
+ scrollbar-width: none;
50
+ }
51
+
52
+ :global(*)::-webkit-scrollbar {
53
+ display: none;
54
+ }
55
+
47
56
  :global(html),
48
57
  :global(body),
49
58
  :global(#root) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "castle-web-cli",
3
- "version": "0.4.34",
3
+ "version": "0.4.35",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "castle-web": "./dist/index.js"