@luckydraw/cumulus 1.0.44 → 1.0.45
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/CHANGELOG.md +11 -0
- package/README.md +1 -0
- package/dist/gateway/adapters/webchat.d.ts.map +1 -1
- package/dist/gateway/adapters/webchat.js +22 -1
- package/dist/gateway/adapters/webchat.js.map +1 -1
- package/dist/gateway/jobs.d.ts +6 -0
- package/dist/gateway/jobs.d.ts.map +1 -1
- package/dist/gateway/jobs.js +12 -0
- package/dist/gateway/jobs.js.map +1 -1
- package/dist/gateway/server.d.ts +2 -0
- package/dist/gateway/server.d.ts.map +1 -1
- package/dist/gateway/server.js +108 -0
- package/dist/gateway/server.js.map +1 -1
- package/dist/gateway/static/widget.js +205 -0
- package/dist/gateway/thread-rename.d.ts +108 -0
- package/dist/gateway/thread-rename.d.ts.map +1 -0
- package/dist/gateway/thread-rename.js +208 -0
- package/dist/gateway/thread-rename.js.map +1 -0
- package/dist/lib/content-store.d.ts +11 -0
- package/dist/lib/content-store.d.ts.map +1 -1
- package/dist/lib/content-store.js +34 -0
- package/dist/lib/content-store.js.map +1 -1
- package/dist/lib/worktree.d.ts +18 -0
- package/dist/lib/worktree.d.ts.map +1 -1
- package/dist/lib/worktree.js +32 -0
- package/dist/lib/worktree.js.map +1 -1
- package/package.json +1 -1
|
@@ -5652,6 +5652,16 @@
|
|
|
5652
5652
|
menu.appendChild(coItem);
|
|
5653
5653
|
}
|
|
5654
5654
|
|
|
5655
|
+
var renameItem = document.createElement('button');
|
|
5656
|
+
renameItem.className = 'cumulus-context-menu-item';
|
|
5657
|
+
renameItem.textContent = 'Rename thread…';
|
|
5658
|
+
renameItem.setAttribute('data-testid', 'webchat-thread-rename');
|
|
5659
|
+
renameItem.addEventListener('click', function () {
|
|
5660
|
+
dismissContextMenu();
|
|
5661
|
+
showThreadRenameDialog(threadName, master);
|
|
5662
|
+
});
|
|
5663
|
+
menu.appendChild(renameItem);
|
|
5664
|
+
|
|
5655
5665
|
var deleteItem = document.createElement('button');
|
|
5656
5666
|
deleteItem.className = 'cumulus-context-menu-item danger';
|
|
5657
5667
|
deleteItem.textContent = 'Delete thread';
|
|
@@ -5835,6 +5845,190 @@
|
|
|
5835
5845
|
xhr.send(JSON.stringify({ label: label }));
|
|
5836
5846
|
}
|
|
5837
5847
|
|
|
5848
|
+
// ── Thread rename (task 186) ──
|
|
5849
|
+
|
|
5850
|
+
/**
|
|
5851
|
+
* Re-key every piece of client state that names a thread. One function so
|
|
5852
|
+
* a `thread_renamed` from the server and a rename this tab just made take
|
|
5853
|
+
* the same path; a list missed here is a sidebar row that 404s on click.
|
|
5854
|
+
*/
|
|
5855
|
+
function applyThreadRename(from, to) {
|
|
5856
|
+
for (var i = 0; i < allThreads.length; i++) {
|
|
5857
|
+
if (allThreads[i].name === from) allThreads[i].name = to;
|
|
5858
|
+
if (allThreads[i].master === from) allThreads[i].master = to;
|
|
5859
|
+
}
|
|
5860
|
+
if (threadStates[from]) {
|
|
5861
|
+
threadStates[to] = threadStates[from];
|
|
5862
|
+
delete threadStates[from];
|
|
5863
|
+
}
|
|
5864
|
+
var vi = visibleThreads.indexOf(from);
|
|
5865
|
+
if (vi !== -1) visibleThreads[vi] = to;
|
|
5866
|
+
if (busyThreads[from]) {
|
|
5867
|
+
busyThreads[to] = true;
|
|
5868
|
+
delete busyThreads[from];
|
|
5869
|
+
}
|
|
5870
|
+
if (unreadThreads[from]) {
|
|
5871
|
+
unreadThreads[to] = unreadThreads[from];
|
|
5872
|
+
delete unreadThreads[from];
|
|
5873
|
+
}
|
|
5874
|
+
if (collapsedMasters[from]) {
|
|
5875
|
+
collapsedMasters[to] = true;
|
|
5876
|
+
delete collapsedMasters[from];
|
|
5877
|
+
try {
|
|
5878
|
+
localStorage.setItem('cumulus-collapsed-masters', JSON.stringify(collapsedMasters));
|
|
5879
|
+
} catch {
|
|
5880
|
+
/* storage unavailable — the collapse state is cosmetic */
|
|
5881
|
+
}
|
|
5882
|
+
}
|
|
5883
|
+
}
|
|
5884
|
+
|
|
5885
|
+
function renameThread(from, to, cb) {
|
|
5886
|
+
var xhr = new XMLHttpRequest();
|
|
5887
|
+
xhr.open('POST', '/api/thread/' + encodeURIComponent(from) + '/rename');
|
|
5888
|
+
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
5889
|
+
xhr.setRequestHeader('X-API-Key', activeApiKey);
|
|
5890
|
+
xhr.onload = function () {
|
|
5891
|
+
var body = {};
|
|
5892
|
+
try {
|
|
5893
|
+
body = JSON.parse(xhr.responseText || '{}');
|
|
5894
|
+
} catch {
|
|
5895
|
+
/* fall through to the status-based message below */
|
|
5896
|
+
}
|
|
5897
|
+
if (xhr.status === 200) {
|
|
5898
|
+
cb(null, body);
|
|
5899
|
+
return;
|
|
5900
|
+
}
|
|
5901
|
+
cb(body.error || 'Could not rename the thread (' + xhr.status + ').');
|
|
5902
|
+
};
|
|
5903
|
+
xhr.onerror = function () {
|
|
5904
|
+
cb('Could not reach the gateway.');
|
|
5905
|
+
};
|
|
5906
|
+
xhr.send(JSON.stringify({ name: to }));
|
|
5907
|
+
}
|
|
5908
|
+
|
|
5909
|
+
function showThreadRenameDialog(threadName, master) {
|
|
5910
|
+
var existing = document.querySelector('.cumulus-confirm-dialog[data-context="rename"]');
|
|
5911
|
+
if (existing) existing.remove();
|
|
5912
|
+
|
|
5913
|
+
// A co-thread keeps its master's prefix (the server enforces it); the
|
|
5914
|
+
// dialog shows the prefix as fixed text and edits only the label.
|
|
5915
|
+
var prefix = master ? master + '-' : '';
|
|
5916
|
+
var current = threadName.slice(prefix.length);
|
|
5917
|
+
|
|
5918
|
+
var dialog = document.createElement('div');
|
|
5919
|
+
dialog.className = 'cumulus-confirm-dialog';
|
|
5920
|
+
dialog.setAttribute('data-context', 'rename');
|
|
5921
|
+
dialog.style.cssText =
|
|
5922
|
+
'position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.6); z-index: 200; display: flex; align-items: center; justify-content: center;';
|
|
5923
|
+
|
|
5924
|
+
var box = document.createElement('div');
|
|
5925
|
+
box.className = 'cumulus-confirm-dialog-box';
|
|
5926
|
+
|
|
5927
|
+
var title = document.createElement('div');
|
|
5928
|
+
title.className = 'cumulus-confirm-dialog-title';
|
|
5929
|
+
title.textContent = master ? 'Rename co-thread' : 'Rename thread';
|
|
5930
|
+
box.appendChild(title);
|
|
5931
|
+
|
|
5932
|
+
var text = document.createElement('div');
|
|
5933
|
+
text.className = 'cumulus-confirm-dialog-text';
|
|
5934
|
+
text.textContent = master
|
|
5935
|
+
? 'Keeps "' + master + '-" so it stays a co-thread of ' + master + '.'
|
|
5936
|
+
: 'Everything the thread has — history, memory, settings, jobs, schedules — moves with it.';
|
|
5937
|
+
box.appendChild(text);
|
|
5938
|
+
|
|
5939
|
+
var input = document.createElement('input');
|
|
5940
|
+
input.type = 'text';
|
|
5941
|
+
input.className = 'cumulus-co-thread-input';
|
|
5942
|
+
input.value = current;
|
|
5943
|
+
input.setAttribute('data-testid', 'webchat-thread-rename-input');
|
|
5944
|
+
box.appendChild(input);
|
|
5945
|
+
|
|
5946
|
+
var preview = document.createElement('div');
|
|
5947
|
+
preview.className = 'cumulus-confirm-dialog-warn';
|
|
5948
|
+
preview.setAttribute('data-testid', 'webchat-thread-rename-preview');
|
|
5949
|
+
box.appendChild(preview);
|
|
5950
|
+
|
|
5951
|
+
// Mirrors THREAD_NAME_RE / CO_THREAD_LABEL_RE in thread-rename.ts. The
|
|
5952
|
+
// server is authoritative; this only turns a 400 into a message written
|
|
5953
|
+
// before the request is sent.
|
|
5954
|
+
var NAME_OK = master ? /^[a-zA-Z0-9_]+$/ : /^[a-zA-Z0-9_-]+$/;
|
|
5955
|
+
function refreshPreview() {
|
|
5956
|
+
var value = input.value.trim();
|
|
5957
|
+
if (!value) {
|
|
5958
|
+
preview.textContent = master
|
|
5959
|
+
? 'Letters, numbers and underscores.'
|
|
5960
|
+
: 'Letters, numbers, hyphens and underscores.';
|
|
5961
|
+
return false;
|
|
5962
|
+
}
|
|
5963
|
+
if (!NAME_OK.test(value)) {
|
|
5964
|
+
preview.textContent = master
|
|
5965
|
+
? 'Letters, numbers and underscores only — no spaces or hyphens.'
|
|
5966
|
+
: 'Letters, numbers, hyphens and underscores only — no spaces.';
|
|
5967
|
+
return false;
|
|
5968
|
+
}
|
|
5969
|
+
if (prefix + value === threadName) {
|
|
5970
|
+
preview.textContent = 'That is the current name.';
|
|
5971
|
+
return false;
|
|
5972
|
+
}
|
|
5973
|
+
preview.textContent = 'Renames to: ' + prefix + value;
|
|
5974
|
+
return true;
|
|
5975
|
+
}
|
|
5976
|
+
refreshPreview();
|
|
5977
|
+
input.addEventListener('input', refreshPreview);
|
|
5978
|
+
|
|
5979
|
+
var actions = document.createElement('div');
|
|
5980
|
+
actions.className = 'cumulus-confirm-dialog-actions';
|
|
5981
|
+
|
|
5982
|
+
var cancelBtn = document.createElement('button');
|
|
5983
|
+
cancelBtn.className = 'cumulus-confirm-dialog-cancel';
|
|
5984
|
+
cancelBtn.textContent = 'Cancel';
|
|
5985
|
+
cancelBtn.addEventListener('click', function () {
|
|
5986
|
+
dialog.remove();
|
|
5987
|
+
});
|
|
5988
|
+
actions.appendChild(cancelBtn);
|
|
5989
|
+
|
|
5990
|
+
var renameBtn = document.createElement('button');
|
|
5991
|
+
renameBtn.className = 'cumulus-confirm-dialog-confirm';
|
|
5992
|
+
renameBtn.setAttribute('data-testid', 'webchat-thread-rename-confirm');
|
|
5993
|
+
renameBtn.textContent = 'Rename';
|
|
5994
|
+
function submit() {
|
|
5995
|
+
if (!refreshPreview()) return;
|
|
5996
|
+
renameBtn.disabled = true;
|
|
5997
|
+
renameBtn.textContent = 'Renaming…';
|
|
5998
|
+
var to = prefix + input.value.trim();
|
|
5999
|
+
renameThread(threadName, to, function (err) {
|
|
6000
|
+
if (err) {
|
|
6001
|
+
renameBtn.disabled = false;
|
|
6002
|
+
renameBtn.textContent = 'Rename';
|
|
6003
|
+
preview.textContent = err;
|
|
6004
|
+
return;
|
|
6005
|
+
}
|
|
6006
|
+
dialog.remove();
|
|
6007
|
+
// The server also broadcasts thread_renamed to every tab, this one
|
|
6008
|
+
// included; applying it here too means no flash of the old name.
|
|
6009
|
+
applyThreadRename(threadName, to);
|
|
6010
|
+
renderSidebar();
|
|
6011
|
+
renderContentArea();
|
|
6012
|
+
if (connection) connection.send({ type: 'threads' });
|
|
6013
|
+
});
|
|
6014
|
+
}
|
|
6015
|
+
renameBtn.addEventListener('click', submit);
|
|
6016
|
+
input.addEventListener('keydown', function (e) {
|
|
6017
|
+
if (e.key === 'Enter') submit();
|
|
6018
|
+
if (e.key === 'Escape') dialog.remove();
|
|
6019
|
+
});
|
|
6020
|
+
actions.appendChild(renameBtn);
|
|
6021
|
+
|
|
6022
|
+
box.appendChild(actions);
|
|
6023
|
+
dialog.appendChild(box);
|
|
6024
|
+
dialog.addEventListener('click', function (e) {
|
|
6025
|
+
if (e.target === dialog) dialog.remove();
|
|
6026
|
+
});
|
|
6027
|
+
document.body.appendChild(dialog);
|
|
6028
|
+
input.focus();
|
|
6029
|
+
input.select();
|
|
6030
|
+
}
|
|
6031
|
+
|
|
5838
6032
|
// ── Thread delete confirmation ──
|
|
5839
6033
|
function showThreadDeleteConfirm(threadName) {
|
|
5840
6034
|
// Remove any existing confirm dialogs
|
|
@@ -10595,6 +10789,17 @@
|
|
|
10595
10789
|
}
|
|
10596
10790
|
break;
|
|
10597
10791
|
|
|
10792
|
+
case 'thread_renamed':
|
|
10793
|
+
// Task 186 — re-key this tab's state, then ask for the listing, which
|
|
10794
|
+
// is what carries `master` and the per-thread counts.
|
|
10795
|
+
if (data.from && data.to) {
|
|
10796
|
+
applyThreadRename(data.from, data.to);
|
|
10797
|
+
renderSidebar();
|
|
10798
|
+
renderContentArea();
|
|
10799
|
+
if (connection) connection.send({ type: 'threads' });
|
|
10800
|
+
}
|
|
10801
|
+
break;
|
|
10802
|
+
|
|
10598
10803
|
case 'thread_deleted':
|
|
10599
10804
|
// Server confirms thread deleted; remove from sidebar and panels
|
|
10600
10805
|
if (data.threadName) {
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task 186 — rename a thread or a co-thread.
|
|
3
|
+
*
|
|
4
|
+
* The thread's NAME is the key of every artefact the gateway keeps about it
|
|
5
|
+
* (task 185 lists them; the task doc for 186 repeats the list). So a rename is
|
|
6
|
+
* not a field update: it is one migration that moves every name-keyed row at
|
|
7
|
+
* once, and this module is the only place that migration is written. A second
|
|
8
|
+
* caller — an MCP tool, the CLI — calls `executeThreadRename`; there is no
|
|
9
|
+
* other path, because a path that moved most of the rows would leave a thread
|
|
10
|
+
* that half-exists under two names (Rule #8).
|
|
11
|
+
*
|
|
12
|
+
* Two phases, deliberately separate:
|
|
13
|
+
*
|
|
14
|
+
* 1. `planThreadRename` — validates and computes every move, including the
|
|
15
|
+
* cascade when a master is renamed. Pure apart from the context callbacks,
|
|
16
|
+
* so the six rules it enforces are testable without a filesystem, and so
|
|
17
|
+
* nothing moves until the WHOLE plan is legal.
|
|
18
|
+
* 2. `executeThreadRename` — moves files, rewrites the master's `coThreads`,
|
|
19
|
+
* moves worktrees, appends corrected attribution lines. The caller (server)
|
|
20
|
+
* then re-keys its own in-memory maps and tells the sockets.
|
|
21
|
+
*/
|
|
22
|
+
import type { NamespaceConfig } from './config.js';
|
|
23
|
+
/** The alphabet `create_thread` sanitises to. A rename refuses instead of sanitising. */
|
|
24
|
+
export declare const THREAD_NAME_RE: RegExp;
|
|
25
|
+
/** Mirrors CO_THREAD_LABEL in server.ts: the part of a co-thread's name after `<master>-`. */
|
|
26
|
+
export declare const CO_THREAD_LABEL_RE: RegExp;
|
|
27
|
+
/**
|
|
28
|
+
* Every per-thread file or directory under the threads dir, by extension. The
|
|
29
|
+
* same list `handleDeleteThread` walks, plus the streaming scratch file. A
|
|
30
|
+
* rename that missed one would leave an orphan that reattaches to nothing.
|
|
31
|
+
*/
|
|
32
|
+
export declare const THREAD_FILE_EXTENSIONS: readonly [".jsonl", ".embeddings.json", ".embeddings.bin", ".segments.json", ".adaptive.json", ".config.json", ".sessions", ".content", ".prompts", ".streaming.tmp"];
|
|
33
|
+
/** A refused plan. `status` is the HTTP status the endpoint answers with. */
|
|
34
|
+
export declare class ThreadRenameError extends Error {
|
|
35
|
+
readonly status: number;
|
|
36
|
+
constructor(status: number, message: string);
|
|
37
|
+
}
|
|
38
|
+
export interface RenameMove {
|
|
39
|
+
from: string;
|
|
40
|
+
to: string;
|
|
41
|
+
}
|
|
42
|
+
export interface ThreadRenamePlan {
|
|
43
|
+
from: string;
|
|
44
|
+
to: string;
|
|
45
|
+
/** Set when the renamed thread is a co-thread: whose list to rewrite. */
|
|
46
|
+
coThreadMaster?: string;
|
|
47
|
+
/** Cascaded co-thread renames when a master is renamed (empty otherwise). */
|
|
48
|
+
coThreads: RenameMove[];
|
|
49
|
+
/** Every move, the thread itself first. */
|
|
50
|
+
moves: RenameMove[];
|
|
51
|
+
}
|
|
52
|
+
export interface PlanContext {
|
|
53
|
+
namespaces: NamespaceConfig[];
|
|
54
|
+
/** Any artefact under any extension exists for this name. */
|
|
55
|
+
threadExists(name: string): boolean;
|
|
56
|
+
/** The thread is mid-turn right now. */
|
|
57
|
+
threadBusy(name: string): boolean;
|
|
58
|
+
/** Master of a registered co-thread, else undefined. */
|
|
59
|
+
coThreadMasterOf(name: string): string | undefined;
|
|
60
|
+
/** The master's registered co-thread list (its EXACT config). */
|
|
61
|
+
coThreadsOf(master: string): Promise<string[]>;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Validate a rename and compute every move it implies.
|
|
65
|
+
*
|
|
66
|
+
* Rules, in the order they are checked (each one's failure names it):
|
|
67
|
+
* 1. `from` exists.
|
|
68
|
+
* 2. `to` has the thread-name shape and differs from `from`.
|
|
69
|
+
* 3. Neither name is a namespace base, and both fall in the same namespace.
|
|
70
|
+
* 4. A co-thread keeps `<master>-` and its new label has the label shape.
|
|
71
|
+
* 5. A master's co-threads cascade: `<from>-x` → `<to>-x`.
|
|
72
|
+
* 6. No target name exists; no source is mid-turn. Checked for the WHOLE
|
|
73
|
+
* cascade before anything is reported legal.
|
|
74
|
+
*/
|
|
75
|
+
export declare function planThreadRename(from: string, to: string, ctx: PlanContext): Promise<ThreadRenamePlan>;
|
|
76
|
+
export interface ExecuteContext {
|
|
77
|
+
threadsDir: string;
|
|
78
|
+
/** The project directory a master's worktrees hang off. */
|
|
79
|
+
projectDirFor(master: string): Promise<string | undefined>;
|
|
80
|
+
}
|
|
81
|
+
export interface ThreadRenameResult {
|
|
82
|
+
from: string;
|
|
83
|
+
to: string;
|
|
84
|
+
coThreads: RenameMove[];
|
|
85
|
+
/** Extensions actually moved, per thread. */
|
|
86
|
+
moved: Record<string, string[]>;
|
|
87
|
+
/** Attribution entries rewritten in the affected content store. */
|
|
88
|
+
attributionUpdated: number;
|
|
89
|
+
/** Worktree outcomes for every co-thread move. */
|
|
90
|
+
worktrees: Array<RenameMove & {
|
|
91
|
+
moved: boolean;
|
|
92
|
+
detail?: string;
|
|
93
|
+
}>;
|
|
94
|
+
}
|
|
95
|
+
/** Move every existing artefact of `from` to `to`. Returns the extensions moved. */
|
|
96
|
+
export declare function renameThreadFiles(threadsDir: string, from: string, to: string): string[];
|
|
97
|
+
/**
|
|
98
|
+
* Carry out a legal plan. Order matters:
|
|
99
|
+
*
|
|
100
|
+
* - The project dir is read BEFORE the files move: for a master it lives in
|
|
101
|
+
* the config file that is about to change name.
|
|
102
|
+
* - Files move before the `coThreads` rewrite, because for a master the list
|
|
103
|
+
* is written into the config under its NEW name.
|
|
104
|
+
* - Worktrees move from the master's checkout, which does not move.
|
|
105
|
+
* - Attribution is appended last, into the store under its new path.
|
|
106
|
+
*/
|
|
107
|
+
export declare function executeThreadRename(plan: ThreadRenamePlan, ctx: ExecuteContext): Promise<ThreadRenameResult>;
|
|
108
|
+
//# sourceMappingURL=thread-rename.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-rename.d.ts","sourceRoot":"","sources":["../../src/gateway/thread-rename.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AASH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,yFAAyF;AACzF,eAAO,MAAM,cAAc,QAAqB,CAAC;AACjD,8FAA8F;AAC9F,eAAO,MAAM,kBAAkB,QAAoB,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,uKAWzB,CAAC;AAEX,6EAA6E;AAC7E,qBAAa,iBAAkB,SAAQ,KAAK;aAExB,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EAC9B,OAAO,EAAE,MAAM;CAKlB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,SAAS,EAAE,UAAU,EAAE,CAAC;IACxB,2CAA2C;IAC3C,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,6DAA6D;IAC7D,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC,wCAAwC;IACxC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,wDAAwD;IACxD,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACnD,iEAAiE;IACjE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAChD;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,gBAAgB,CAAC,CAuB3B;AA4ED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,UAAU,EAAE,CAAC;IACxB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAChC,mEAAmE;IACnE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kDAAkD;IAClD,SAAS,EAAE,KAAK,CAAC,UAAU,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpE;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CASxF;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,gBAAgB,EACtB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,kBAAkB,CAAC,CA4C7B"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task 186 — rename a thread or a co-thread.
|
|
3
|
+
*
|
|
4
|
+
* The thread's NAME is the key of every artefact the gateway keeps about it
|
|
5
|
+
* (task 185 lists them; the task doc for 186 repeats the list). So a rename is
|
|
6
|
+
* not a field update: it is one migration that moves every name-keyed row at
|
|
7
|
+
* once, and this module is the only place that migration is written. A second
|
|
8
|
+
* caller — an MCP tool, the CLI — calls `executeThreadRename`; there is no
|
|
9
|
+
* other path, because a path that moved most of the rows would leave a thread
|
|
10
|
+
* that half-exists under two names (Rule #8).
|
|
11
|
+
*
|
|
12
|
+
* Two phases, deliberately separate:
|
|
13
|
+
*
|
|
14
|
+
* 1. `planThreadRename` — validates and computes every move, including the
|
|
15
|
+
* cascade when a master is renamed. Pure apart from the context callbacks,
|
|
16
|
+
* so the six rules it enforces are testable without a filesystem, and so
|
|
17
|
+
* nothing moves until the WHOLE plan is legal.
|
|
18
|
+
* 2. `executeThreadRename` — moves files, rewrites the master's `coThreads`,
|
|
19
|
+
* moves worktrees, appends corrected attribution lines. The caller (server)
|
|
20
|
+
* then re-keys its own in-memory maps and tells the sockets.
|
|
21
|
+
*/
|
|
22
|
+
import * as fs from 'fs';
|
|
23
|
+
import * as path from 'path';
|
|
24
|
+
import { loadThreadConfigExact, saveThreadConfig } from '../lib/config.js';
|
|
25
|
+
import { ContentStore } from '../lib/content-store.js';
|
|
26
|
+
import { moveCoThreadWorktree } from '../lib/worktree.js';
|
|
27
|
+
import { namespaceForThread } from './namespaces.js';
|
|
28
|
+
/** The alphabet `create_thread` sanitises to. A rename refuses instead of sanitising. */
|
|
29
|
+
export const THREAD_NAME_RE = /^[a-zA-Z0-9_-]+$/;
|
|
30
|
+
/** Mirrors CO_THREAD_LABEL in server.ts: the part of a co-thread's name after `<master>-`. */
|
|
31
|
+
export const CO_THREAD_LABEL_RE = /^[a-zA-Z0-9_]+$/;
|
|
32
|
+
/**
|
|
33
|
+
* Every per-thread file or directory under the threads dir, by extension. The
|
|
34
|
+
* same list `handleDeleteThread` walks, plus the streaming scratch file. A
|
|
35
|
+
* rename that missed one would leave an orphan that reattaches to nothing.
|
|
36
|
+
*/
|
|
37
|
+
export const THREAD_FILE_EXTENSIONS = [
|
|
38
|
+
'.jsonl',
|
|
39
|
+
'.embeddings.json',
|
|
40
|
+
'.embeddings.bin',
|
|
41
|
+
'.segments.json',
|
|
42
|
+
'.adaptive.json',
|
|
43
|
+
'.config.json',
|
|
44
|
+
'.sessions',
|
|
45
|
+
'.content',
|
|
46
|
+
'.prompts',
|
|
47
|
+
'.streaming.tmp',
|
|
48
|
+
];
|
|
49
|
+
/** A refused plan. `status` is the HTTP status the endpoint answers with. */
|
|
50
|
+
export class ThreadRenameError extends Error {
|
|
51
|
+
status;
|
|
52
|
+
constructor(status, message) {
|
|
53
|
+
super(message);
|
|
54
|
+
this.status = status;
|
|
55
|
+
this.name = 'ThreadRenameError';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Validate a rename and compute every move it implies.
|
|
60
|
+
*
|
|
61
|
+
* Rules, in the order they are checked (each one's failure names it):
|
|
62
|
+
* 1. `from` exists.
|
|
63
|
+
* 2. `to` has the thread-name shape and differs from `from`.
|
|
64
|
+
* 3. Neither name is a namespace base, and both fall in the same namespace.
|
|
65
|
+
* 4. A co-thread keeps `<master>-` and its new label has the label shape.
|
|
66
|
+
* 5. A master's co-threads cascade: `<from>-x` → `<to>-x`.
|
|
67
|
+
* 6. No target name exists; no source is mid-turn. Checked for the WHOLE
|
|
68
|
+
* cascade before anything is reported legal.
|
|
69
|
+
*/
|
|
70
|
+
export async function planThreadRename(from, to, ctx) {
|
|
71
|
+
if (!ctx.threadExists(from)) {
|
|
72
|
+
throw new ThreadRenameError(404, `Thread "${from}" does not exist.`);
|
|
73
|
+
}
|
|
74
|
+
if (!THREAD_NAME_RE.test(to)) {
|
|
75
|
+
throw new ThreadRenameError(400, 'A thread name is letters, numbers, hyphens and underscores only (no spaces or slashes).');
|
|
76
|
+
}
|
|
77
|
+
if (to === from) {
|
|
78
|
+
throw new ThreadRenameError(400, `"${from}" is already this thread's name.`);
|
|
79
|
+
}
|
|
80
|
+
assertNamespacePreserved(from, to, ctx.namespaces);
|
|
81
|
+
const coThreadMaster = ctx.coThreadMasterOf(from);
|
|
82
|
+
if (coThreadMaster)
|
|
83
|
+
assertCoThreadShape(from, to, coThreadMaster);
|
|
84
|
+
const coThreads = coThreadMaster ? [] : cascadeMoves(from, to, await ctx.coThreadsOf(from));
|
|
85
|
+
const moves = [{ from, to }, ...coThreads];
|
|
86
|
+
assertMovesLegal(from, moves, ctx);
|
|
87
|
+
return { from, to, ...(coThreadMaster ? { coThreadMaster } : {}), coThreads, moves };
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Rule 3 — a namespace is a thread-name prefix and a capability boundary
|
|
91
|
+
* (task 097): a rename must not move a thread across one, and the base
|
|
92
|
+
* thread's name IS the namespace.
|
|
93
|
+
*/
|
|
94
|
+
function assertNamespacePreserved(from, to, namespaces) {
|
|
95
|
+
const nsBases = new Set(namespaces.map(ns => ns.name));
|
|
96
|
+
if (nsBases.has(from)) {
|
|
97
|
+
throw new ThreadRenameError(400, `"${from}" is the base thread of a namespace; its name is the namespace and cannot change.`);
|
|
98
|
+
}
|
|
99
|
+
if (nsBases.has(to)) {
|
|
100
|
+
throw new ThreadRenameError(400, `"${to}" is the name of a namespace.`);
|
|
101
|
+
}
|
|
102
|
+
const nsFrom = namespaceForThread(from, namespaces);
|
|
103
|
+
const nsTo = namespaceForThread(to, namespaces);
|
|
104
|
+
if (nsFrom !== nsTo) {
|
|
105
|
+
throw new ThreadRenameError(400, nsFrom
|
|
106
|
+
? `"${from}" belongs to the "${nsFrom}" namespace, so its new name must keep the "${nsFrom}-" prefix.`
|
|
107
|
+
: `"${to}" would move the thread into the "${nsTo}" namespace.`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Rule 4 — a co-thread resolves to its master by prefix chain plus
|
|
112
|
+
* registration. A name that stops starting with `<master>-` loses the shared
|
|
113
|
+
* store and the worktree in one stroke.
|
|
114
|
+
*/
|
|
115
|
+
function assertCoThreadShape(from, to, master) {
|
|
116
|
+
const prefix = `${master}-`;
|
|
117
|
+
const label = to.startsWith(prefix) ? to.slice(prefix.length) : '';
|
|
118
|
+
if (!label || !CO_THREAD_LABEL_RE.test(label)) {
|
|
119
|
+
throw new ThreadRenameError(400, `"${from}" is a co-thread of "${master}", so its new name must be "${prefix}<label>" with a label of letters, numbers or underscores.`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/** Rule 5 — a master's registered co-threads follow it: `<from>-x` → `<to>-x`. */
|
|
123
|
+
function cascadeMoves(from, to, registered) {
|
|
124
|
+
return registered.map(name => {
|
|
125
|
+
if (!name.startsWith(`${from}-`)) {
|
|
126
|
+
throw new ThreadRenameError(409, `Registered co-thread "${name}" does not carry the "${from}-" prefix; fix the registration before renaming.`);
|
|
127
|
+
}
|
|
128
|
+
return { from: name, to: `${to}${name.slice(from.length)}` };
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/** Rule 6 — over the WHOLE plan, before anything is reported legal. */
|
|
132
|
+
function assertMovesLegal(from, moves, ctx) {
|
|
133
|
+
for (const move of moves) {
|
|
134
|
+
if (ctx.threadExists(move.to)) {
|
|
135
|
+
throw new ThreadRenameError(409, `A thread named "${move.to}" already exists.`);
|
|
136
|
+
}
|
|
137
|
+
if (ctx.threadBusy(move.from)) {
|
|
138
|
+
throw new ThreadRenameError(409, move.from === from
|
|
139
|
+
? `"${from}" is running a turn; rename it once it is idle.`
|
|
140
|
+
: `Co-thread "${move.from}" is running a turn; rename once it is idle.`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/** Move every existing artefact of `from` to `to`. Returns the extensions moved. */
|
|
145
|
+
export function renameThreadFiles(threadsDir, from, to) {
|
|
146
|
+
const moved = [];
|
|
147
|
+
for (const ext of THREAD_FILE_EXTENSIONS) {
|
|
148
|
+
const source = path.join(threadsDir, `${from}${ext}`);
|
|
149
|
+
if (!fs.existsSync(source))
|
|
150
|
+
continue;
|
|
151
|
+
fs.renameSync(source, path.join(threadsDir, `${to}${ext}`));
|
|
152
|
+
moved.push(ext);
|
|
153
|
+
}
|
|
154
|
+
return moved;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Carry out a legal plan. Order matters:
|
|
158
|
+
*
|
|
159
|
+
* - The project dir is read BEFORE the files move: for a master it lives in
|
|
160
|
+
* the config file that is about to change name.
|
|
161
|
+
* - Files move before the `coThreads` rewrite, because for a master the list
|
|
162
|
+
* is written into the config under its NEW name.
|
|
163
|
+
* - Worktrees move from the master's checkout, which does not move.
|
|
164
|
+
* - Attribution is appended last, into the store under its new path.
|
|
165
|
+
*/
|
|
166
|
+
export async function executeThreadRename(plan, ctx) {
|
|
167
|
+
const master = plan.coThreadMaster ?? plan.from;
|
|
168
|
+
const masterDir = await ctx.projectDirFor(master);
|
|
169
|
+
const moved = {};
|
|
170
|
+
for (const move of plan.moves) {
|
|
171
|
+
moved[move.from] = renameThreadFiles(ctx.threadsDir, move.from, move.to);
|
|
172
|
+
}
|
|
173
|
+
if (plan.coThreadMaster) {
|
|
174
|
+
const config = await loadThreadConfigExact(plan.coThreadMaster);
|
|
175
|
+
await saveThreadConfig(plan.coThreadMaster, {
|
|
176
|
+
coThreads: (config.coThreads ?? []).map(n => (n === plan.from ? plan.to : n)),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
else if (plan.coThreads.length > 0) {
|
|
180
|
+
await saveThreadConfig(plan.to, { coThreads: plan.coThreads.map(m => m.to) });
|
|
181
|
+
}
|
|
182
|
+
const worktrees = [];
|
|
183
|
+
const coMoves = plan.coThreadMaster ? [{ from: plan.from, to: plan.to }] : plan.coThreads;
|
|
184
|
+
for (const move of coMoves) {
|
|
185
|
+
const outcome = await moveCoThreadWorktree(move.from, move.to, masterDir);
|
|
186
|
+
worktrees.push({ ...move, ...outcome });
|
|
187
|
+
}
|
|
188
|
+
// The store that carries this thread's tags: its own for a plain thread or a
|
|
189
|
+
// master (now under the new name), the master's for a co-thread.
|
|
190
|
+
const storeOwner = plan.coThreadMaster ?? plan.to;
|
|
191
|
+
const storePath = path.join(ctx.threadsDir, `${storeOwner}.content`);
|
|
192
|
+
let attributionUpdated = 0;
|
|
193
|
+
if (fs.existsSync(storePath)) {
|
|
194
|
+
const mapping = {};
|
|
195
|
+
for (const move of plan.moves)
|
|
196
|
+
mapping[move.from] = move.to;
|
|
197
|
+
attributionUpdated = await new ContentStore(storePath).renameThreads(mapping);
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
from: plan.from,
|
|
201
|
+
to: plan.to,
|
|
202
|
+
coThreads: plan.coThreads,
|
|
203
|
+
moved,
|
|
204
|
+
attributionUpdated,
|
|
205
|
+
worktrees,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=thread-rename.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-rename.js","sourceRoot":"","sources":["../../src/gateway/thread-rename.ts"],"names":[],"mappings":"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"}
|
|
@@ -377,6 +377,17 @@ export declare class ContentStore {
|
|
|
377
377
|
* later line win.
|
|
378
378
|
*/
|
|
379
379
|
private addThreadAttribution;
|
|
380
|
+
/**
|
|
381
|
+
* Follow a thread rename through the attribution tags (task 186).
|
|
382
|
+
*
|
|
383
|
+
* `mapping` is old name → new name; a master rename passes itself and every
|
|
384
|
+
* cascaded co-thread in one map so the store is walked once. Every entry whose
|
|
385
|
+
* `threads` names a renamed thread gets ONE appended index line with the
|
|
386
|
+
* substitution made — appended, never rewritten, for the same reason as
|
|
387
|
+
* `addThreadAttribution`: a whole-file rewrite is the read-modify-write that
|
|
388
|
+
* lost 8% of ordimor's store (task 148 D1). Returns how many entries changed.
|
|
389
|
+
*/
|
|
390
|
+
renameThreads(mapping: Record<string, string>): Promise<number>;
|
|
380
391
|
/**
|
|
381
392
|
* Store content externally and return metadata.
|
|
382
393
|
* Returns existing content ID if content hash matches (deduplication).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-store.d.ts","sourceRoot":"","sources":["../../src/lib/content-store.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"content-store.d.ts","sourceRoot":"","sources":["../../src/lib/content-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -712,6 +712,40 @@ export class ContentStore {
|
|
|
712
712
|
}
|
|
713
713
|
return updated;
|
|
714
714
|
}
|
|
715
|
+
/**
|
|
716
|
+
* Follow a thread rename through the attribution tags (task 186).
|
|
717
|
+
*
|
|
718
|
+
* `mapping` is old name → new name; a master rename passes itself and every
|
|
719
|
+
* cascaded co-thread in one map so the store is walked once. Every entry whose
|
|
720
|
+
* `threads` names a renamed thread gets ONE appended index line with the
|
|
721
|
+
* substitution made — appended, never rewritten, for the same reason as
|
|
722
|
+
* `addThreadAttribution`: a whole-file rewrite is the read-modify-write that
|
|
723
|
+
* lost 8% of ordimor's store (task 148 D1). Returns how many entries changed.
|
|
724
|
+
*/
|
|
725
|
+
async renameThreads(mapping) {
|
|
726
|
+
const index = await this.loadIndex();
|
|
727
|
+
const touched = [];
|
|
728
|
+
for (const meta of index) {
|
|
729
|
+
const threads = ContentStore.threadsOf(meta);
|
|
730
|
+
if (!threads.some(t => t in mapping))
|
|
731
|
+
continue;
|
|
732
|
+
const renamed = Array.from(new Set(threads.map(t => mapping[t] ?? t)));
|
|
733
|
+
touched.push({ ...meta, metadata: { ...(meta.metadata ?? {}), threads: renamed } });
|
|
734
|
+
}
|
|
735
|
+
if (touched.length === 0)
|
|
736
|
+
return 0;
|
|
737
|
+
let appended = '';
|
|
738
|
+
for (const meta of touched)
|
|
739
|
+
appended += JSON.stringify(meta) + '\n';
|
|
740
|
+
await this.appendIndexLine(appended);
|
|
741
|
+
if (this.cachedIndex !== null && this.cachedIndexPos !== null) {
|
|
742
|
+
this.mergeIndexEntries(this.cachedIndex, this.cachedIndexPos, touched);
|
|
743
|
+
}
|
|
744
|
+
if (this.cachedIndexSize >= 0) {
|
|
745
|
+
this.cachedIndexSize += Buffer.byteLength(appended, 'utf-8');
|
|
746
|
+
}
|
|
747
|
+
return touched.length;
|
|
748
|
+
}
|
|
715
749
|
/**
|
|
716
750
|
* Store content externally and return metadata.
|
|
717
751
|
* Returns existing content ID if content hash matches (deduplication).
|