@cerbur/clutch-dsh-worktree 0.1.6 → 0.1.7

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 (116) hide show
  1. package/README.md +107 -15
  2. package/README.zh.md +86 -10
  3. package/cordis.patch.yml +21 -0
  4. package/lib/client/WorktreeContext.d.ts.map +1 -1
  5. package/lib/client/WorktreeContext.js +2 -2
  6. package/lib/client/WorktreeContext.js.map +1 -1
  7. package/lib/client/WorktreeSurface.d.ts +2 -2
  8. package/lib/client/WorktreeSurface.d.ts.map +1 -1
  9. package/lib/client/WorktreeSurface.js +270 -65
  10. package/lib/client/WorktreeSurface.js.map +1 -1
  11. package/lib/client/entry.d.ts.map +1 -1
  12. package/lib/client/entry.js +84 -2
  13. package/lib/client/entry.js.map +1 -1
  14. package/lib/client/index.d.ts +3 -0
  15. package/lib/client/index.d.ts.map +1 -1
  16. package/lib/client/index.js +2 -0
  17. package/lib/client/index.js.map +1 -1
  18. package/lib/client/locales.d.ts +58 -0
  19. package/lib/client/locales.d.ts.map +1 -1
  20. package/lib/client/locales.js +58 -0
  21. package/lib/client/locales.js.map +1 -1
  22. package/lib/client/session-view.d.ts +34 -0
  23. package/lib/client/session-view.d.ts.map +1 -1
  24. package/lib/client/session-view.js +119 -1
  25. package/lib/client/session-view.js.map +1 -1
  26. package/lib/client/worktree-connection.d.ts +4 -2
  27. package/lib/client/worktree-connection.d.ts.map +1 -1
  28. package/lib/client/worktree-connection.js +4 -0
  29. package/lib/client/worktree-connection.js.map +1 -1
  30. package/lib/client/worktree-error-copy.d.ts +2 -0
  31. package/lib/client/worktree-error-copy.d.ts.map +1 -1
  32. package/lib/client/worktree-error-copy.js +16 -0
  33. package/lib/client/worktree-error-copy.js.map +1 -1
  34. package/lib/client/worktree-permission-icon.d.ts +7 -0
  35. package/lib/client/worktree-permission-icon.d.ts.map +1 -0
  36. package/lib/client/worktree-permission-icon.js +119 -0
  37. package/lib/client/worktree-permission-icon.js.map +1 -0
  38. package/lib/client/worktree-permission.d.ts +21 -0
  39. package/lib/client/worktree-permission.d.ts.map +1 -0
  40. package/lib/client/worktree-permission.js +70 -0
  41. package/lib/client/worktree-permission.js.map +1 -0
  42. package/lib/client/worktree-session-fork.d.ts +65 -0
  43. package/lib/client/worktree-session-fork.d.ts.map +1 -0
  44. package/lib/client/worktree-session-fork.js +174 -0
  45. package/lib/client/worktree-session-fork.js.map +1 -0
  46. package/lib/client/worktree-session-order.d.ts +36 -0
  47. package/lib/client/worktree-session-order.d.ts.map +1 -0
  48. package/lib/client/worktree-session-order.js +215 -0
  49. package/lib/client/worktree-session-order.js.map +1 -0
  50. package/lib/client/worktree-session.d.ts +34 -1
  51. package/lib/client/worktree-session.d.ts.map +1 -1
  52. package/lib/client/worktree-session.js +98 -2
  53. package/lib/client/worktree-session.js.map +1 -1
  54. package/lib/client/worktree-surface-rows.d.ts +4 -4
  55. package/lib/client/worktree-surface-rows.d.ts.map +1 -1
  56. package/lib/client/worktree-surface-rows.js +132 -47
  57. package/lib/client/worktree-surface-rows.js.map +1 -1
  58. package/lib/client/worktree-surface-selectors.d.ts +2 -0
  59. package/lib/client/worktree-surface-selectors.d.ts.map +1 -1
  60. package/lib/client/worktree-surface-selectors.js +8 -0
  61. package/lib/client/worktree-surface-selectors.js.map +1 -1
  62. package/lib/client/worktree-surface-types.d.ts +46 -3
  63. package/lib/client/worktree-surface-types.d.ts.map +1 -1
  64. package/lib/client/worktree-view-actions.d.ts +8 -3
  65. package/lib/client/worktree-view-actions.d.ts.map +1 -1
  66. package/lib/client/worktree-view-actions.js +28 -2
  67. package/lib/client/worktree-view-actions.js.map +1 -1
  68. package/lib/client/worktree-view-errors.d.ts +10 -0
  69. package/lib/client/worktree-view-errors.d.ts.map +1 -1
  70. package/lib/client/worktree-view-errors.js +22 -1
  71. package/lib/client/worktree-view-errors.js.map +1 -1
  72. package/lib/client.js +1473 -201
  73. package/lib/client.js.map +1 -1
  74. package/lib/contract/index.contract.js +2 -0
  75. package/lib/contract/index.contract.js.map +1 -1
  76. package/lib/contract/index.d.ts +6 -2
  77. package/lib/contract/index.d.ts.map +1 -1
  78. package/lib/contract/index.js +4 -0
  79. package/lib/contract/index.js.map +1 -1
  80. package/lib/contract/worktree-permission.d.ts +73 -0
  81. package/lib/contract/worktree-permission.d.ts.map +1 -0
  82. package/lib/contract/worktree-permission.js +32 -0
  83. package/lib/contract/worktree-permission.js.map +1 -0
  84. package/lib/host/index.d.ts +4 -0
  85. package/lib/host/index.d.ts.map +1 -1
  86. package/lib/host/index.js +2 -0
  87. package/lib/host/index.js.map +1 -1
  88. package/lib/host/remote.d.ts +2 -2
  89. package/lib/host/remote.d.ts.map +1 -1
  90. package/lib/host/remote.js +7 -1
  91. package/lib/host/remote.js.map +1 -1
  92. package/lib/host/service.d.ts +3 -1
  93. package/lib/host/service.d.ts.map +1 -1
  94. package/lib/host/service.js +36 -2
  95. package/lib/host/service.js.map +1 -1
  96. package/lib/host/worktree-permission-manager.d.ts +14 -0
  97. package/lib/host/worktree-permission-manager.d.ts.map +1 -0
  98. package/lib/host/worktree-permission-manager.js +111 -0
  99. package/lib/host/worktree-permission-manager.js.map +1 -0
  100. package/lib/host/worktree-permission.d.ts +38 -0
  101. package/lib/host/worktree-permission.d.ts.map +1 -0
  102. package/lib/host/worktree-permission.js +156 -0
  103. package/lib/host/worktree-permission.js.map +1 -0
  104. package/lib/index.d.ts +4 -3
  105. package/lib/index.d.ts.map +1 -1
  106. package/lib/index.js +2 -1
  107. package/lib/index.js.map +1 -1
  108. package/lib/manage/worktree-permission.d.ts +3 -0
  109. package/lib/manage/worktree-permission.d.ts.map +1 -0
  110. package/lib/manage/worktree-permission.js +3 -0
  111. package/lib/manage/worktree-permission.js.map +1 -0
  112. package/lib/typert.host.js +126 -27
  113. package/lib/typert.remote-client.d.ts +5 -1
  114. package/lib/typert.remote-client.d.ts.map +1 -1
  115. package/lib/typert.remote-client.js +126 -27
  116. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-permission-icon.js","sourceRoot":"","sources":["../../src/client/worktree-permission-icon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export interface WorktreeFullAccessConfirmationInput {
2
+ readonly workspaceId: string;
3
+ readonly worktreeId: string;
4
+ readonly sessionId: string;
5
+ readonly cwd: string;
6
+ }
7
+ export interface WorktreeFullAccessConfirmationController {
8
+ readonly getSnapshot: () => WorktreeFullAccessConfirmationInput | undefined;
9
+ readonly subscribe: (listener: () => void) => () => void;
10
+ readonly request: (input: WorktreeFullAccessConfirmationInput) => Promise<boolean>;
11
+ readonly resolve: (confirmed: boolean) => void;
12
+ readonly dispose: () => void;
13
+ }
14
+ export declare function worktreeFullAccessConfirmationMessage(input: WorktreeFullAccessConfirmationInput, locale?: string): string;
15
+ /**
16
+ * Coordinate async permission requests with the one in-page confirmation
17
+ * rendered by the Worktree surface. Requests are serialized so concurrent
18
+ * Worktree Session creations cannot replace one another's dialog.
19
+ */
20
+ export declare function createWorktreeFullAccessConfirmationController(): WorktreeFullAccessConfirmationController;
21
+ //# sourceMappingURL=worktree-permission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-permission.d.ts","sourceRoot":"","sources":["../../src/client/worktree-permission.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mCAAmC;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wCAAwC;IACvD,QAAQ,CAAC,WAAW,EAAE,MAAM,mCAAmC,GAAG,SAAS,CAAC;IAC5E,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IACzD,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,mCAAmC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACnF,QAAQ,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B;AAWD,wBAAgB,qCAAqC,CACnD,KAAK,EAAE,mCAAmC,EAC1C,MAAM,SAAiC,GACtC,MAAM,CAKR;AAED;;;;GAIG;AACH,wBAAgB,8CAA8C,IAC5D,wCAAwC,CAqDzC"}
@@ -0,0 +1,70 @@
1
+ const englishReason = 'This Worktree Session may need Git metadata and linked Worktree files outside the Session directory. '
2
+ + 'Full Access disables filesystem confinement for this Session; approval prompts remain enabled, '
3
+ + 'and network and process policy is unchanged. Continue?';
4
+ const chineseReason = '这个 Worktree Session 可能需要访问 Session 目录之外的 Git 元数据和关联 Worktree 文件。'
5
+ + '完全访问会关闭此 Session 的文件系统沙箱,但会保留审批提示,网络和进程策略不变。'
6
+ + '是否继续?';
7
+ export function worktreeFullAccessConfirmationMessage(input, locale = globalThis.navigator?.language) {
8
+ const reason = locale?.toLocaleLowerCase().startsWith('zh') === true
9
+ ? chineseReason
10
+ : englishReason;
11
+ return `${reason}\n\nWorktree: ${input.cwd}`;
12
+ }
13
+ /**
14
+ * Coordinate async permission requests with the one in-page confirmation
15
+ * rendered by the Worktree surface. Requests are serialized so concurrent
16
+ * Worktree Session creations cannot replace one another's dialog.
17
+ */
18
+ export function createWorktreeFullAccessConfirmationController() {
19
+ let active;
20
+ const queue = [];
21
+ const listeners = new Set();
22
+ let disposed = false;
23
+ const notify = () => {
24
+ for (const listener of listeners)
25
+ listener();
26
+ };
27
+ const showNext = () => {
28
+ if (active !== undefined)
29
+ return;
30
+ active = queue.shift();
31
+ notify();
32
+ };
33
+ const controller = {
34
+ getSnapshot: () => active?.input,
35
+ subscribe: (listener) => {
36
+ listeners.add(listener);
37
+ return () => {
38
+ listeners.delete(listener);
39
+ };
40
+ },
41
+ request: (input) => {
42
+ if (disposed)
43
+ return Promise.resolve(false);
44
+ return new Promise((resolve) => {
45
+ queue.push({ input, resolve });
46
+ showNext();
47
+ });
48
+ },
49
+ resolve: (confirmed) => {
50
+ if (active === undefined)
51
+ return;
52
+ const current = active;
53
+ active = undefined;
54
+ current.resolve(confirmed);
55
+ showNext();
56
+ },
57
+ dispose: () => {
58
+ if (disposed)
59
+ return;
60
+ disposed = true;
61
+ active?.resolve(false);
62
+ active = undefined;
63
+ for (const pending of queue.splice(0))
64
+ pending.resolve(false);
65
+ notify();
66
+ },
67
+ };
68
+ return controller;
69
+ }
70
+ //# sourceMappingURL=worktree-permission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-permission.js","sourceRoot":"","sources":["../../src/client/worktree-permission.ts"],"names":[],"mappings":"AAeA,MAAM,aAAa,GACjB,uGAAuG;MACrG,iGAAiG;MACjG,wDAAwD,CAAC;AAC7D,MAAM,aAAa,GACjB,kEAAkE;MAChE,8CAA8C;MAC9C,OAAO,CAAC;AAEZ,MAAM,UAAU,qCAAqC,CACnD,KAA0C,EAC1C,MAAM,GAAG,UAAU,CAAC,SAAS,EAAE,QAAQ;IAEvC,MAAM,MAAM,GAAG,MAAM,EAAE,iBAAiB,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI;QAClE,CAAC,CAAC,aAAa;QACf,CAAC,CAAC,aAAa,CAAC;IAClB,OAAO,GAAG,MAAM,iBAAiB,KAAK,CAAC,GAAG,EAAE,CAAC;AAC/C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,8CAA8C;IAO5D,IAAI,MAAkC,CAAC;IACvC,MAAM,KAAK,GAAqB,EAAE,CAAC;IACnC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;IACxC,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,MAAM,MAAM,GAAG,GAAS,EAAE;QACxB,KAAK,MAAM,QAAQ,IAAI,SAAS;YAAE,QAAQ,EAAE,CAAC;IAC/C,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,GAAS,EAAE;QAC1B,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO;QACjC,MAAM,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,EAAE,CAAC;IACX,CAAC,CAAC;IAEF,MAAM,UAAU,GAA6C;QAC3D,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,KAAK;QAChC,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE;YACtB,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxB,OAAO,GAAG,EAAE;gBACV,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACjB,IAAI,QAAQ;gBAAE,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC5C,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;gBACtC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;gBAC/B,QAAQ,EAAE,CAAC;YACb,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,CAAC,SAAS,EAAE,EAAE;YACrB,IAAI,MAAM,KAAK,SAAS;gBAAE,OAAO;YACjC,MAAM,OAAO,GAAG,MAAM,CAAC;YACvB,MAAM,GAAG,SAAS,CAAC;YACnB,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC3B,QAAQ,EAAE,CAAC;QACb,CAAC;QACD,OAAO,EAAE,GAAG,EAAE;YACZ,IAAI,QAAQ;gBAAE,OAAO;YACrB,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YACvB,MAAM,GAAG,SAAS,CAAC;YACnB,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;gBAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9D,MAAM,EAAE,CAAC;QACX,CAAC;KACF,CAAC;IAEF,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,65 @@
1
+ import type { SessionBinding } from '../contract/index.js';
2
+ /** The public options accepted by the native DSH Session fork service. */
3
+ export interface WorktreeForkInput {
4
+ readonly sessionId: string;
5
+ readonly atSeq?: number;
6
+ readonly increaseTitle?: boolean;
7
+ }
8
+ /** The lineage facts exposed by DSH's browser Session list. */
9
+ export interface WorktreeForkSessionSummary {
10
+ readonly blank?: boolean;
11
+ readonly parentId?: string;
12
+ readonly origin?: string;
13
+ }
14
+ export interface WorktreeForkSessionListSnapshot {
15
+ readonly phase?: 'pending' | 'ready';
16
+ readonly ids: readonly string[];
17
+ readonly byId: Readonly<Record<string, WorktreeForkSessionSummary | undefined>>;
18
+ }
19
+ export interface WorktreeForkSessionListReader {
20
+ getSnapshot(): WorktreeForkSessionListSnapshot;
21
+ }
22
+ export interface WorktreeForkRecovery {
23
+ readonly key: string;
24
+ readonly sourceSessionId: string;
25
+ readonly childSessionId: string;
26
+ readonly binding?: SessionBinding;
27
+ readonly error: unknown;
28
+ }
29
+ export interface WorktreeForkRecoverySnapshot {
30
+ readonly revision: number;
31
+ readonly pending: readonly WorktreeForkRecovery[];
32
+ }
33
+ export interface WorktreeForkRecoveryStore {
34
+ getSnapshot(): WorktreeForkRecoverySnapshot;
35
+ subscribe(listener: () => void): () => void;
36
+ }
37
+ export interface WorktreeForkCoordinatorOptions {
38
+ /** The unwrapped DSH fork method. */
39
+ readonly fork: (input: WorktreeForkInput) => Promise<string>;
40
+ /** Find the parent's active sidecar binding across all native Workspaces. */
41
+ readonly findBinding: (sessionId: string) => Promise<SessionBinding | undefined>;
42
+ /** Existing Worktree sidecar mutation; it remains the only binding writer. */
43
+ readonly bindSession: (input: {
44
+ workspaceId: string;
45
+ worktreeId: string;
46
+ sessionId: string;
47
+ }) => Promise<unknown>;
48
+ readonly sessions?: WorktreeForkSessionListReader;
49
+ /** Called after a child binding has been committed and before the view refresh. */
50
+ readonly onBound?: (binding: SessionBinding) => void;
51
+ }
52
+ export interface WorktreeForkCoordinator {
53
+ readonly recovery: WorktreeForkRecoveryStore;
54
+ fork(input: WorktreeForkInput): Promise<string>;
55
+ reconcile(): Promise<void>;
56
+ retry(key: string): Promise<boolean>;
57
+ dispose(): void;
58
+ }
59
+ /**
60
+ * Coordinate native Session fork with the plugin-owned Worktree relation.
61
+ * Native Session creation always wins: plugin lookup/bind failures are kept as
62
+ * recovery state and never turn an already-created child into a failed fork.
63
+ */
64
+ export declare function createWorktreeSessionForkCoordinator(options: WorktreeForkCoordinatorOptions): WorktreeForkCoordinator;
65
+ //# sourceMappingURL=worktree-session-fork.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-session-fork.d.ts","sourceRoot":"","sources":["../../src/client/worktree-session-fork.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,+DAA+D;AAC/D,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IACrC,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,0BAA0B,GAAG,SAAS,CAAC,CAAC,CAAC;CACjF;AAED,MAAM,WAAW,6BAA6B;IAC5C,WAAW,IAAI,+BAA+B,CAAC;CAChD;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACnD;AAED,MAAM,WAAW,yBAAyB;IACxC,WAAW,IAAI,4BAA4B,CAAC;IAC5C,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,8BAA8B;IAC7C,qCAAqC;IACrC,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IACjF,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE;QAC5B,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,6BAA6B,CAAC;IAClD,mFAAmF;IACnF,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAC;IAC7C,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,IAAI,IAAI,CAAC;CACjB;AAUD;;;;GAIG;AACH,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,8BAA8B,GACtC,uBAAuB,CAgLzB"}
@@ -0,0 +1,174 @@
1
+ function recoveryKey(sourceSessionId, childSessionId) {
2
+ return `${sourceSessionId}\u0000${childSessionId}`;
3
+ }
4
+ /**
5
+ * Coordinate native Session fork with the plugin-owned Worktree relation.
6
+ * Native Session creation always wins: plugin lookup/bind failures are kept as
7
+ * recovery state and never turn an already-created child into a failed fork.
8
+ */
9
+ export function createWorktreeSessionForkCoordinator(options) {
10
+ let disposed = false;
11
+ let revision = 0;
12
+ let pending = new Map();
13
+ let recoverySnapshot = { revision: 0, pending: [] };
14
+ const subscribers = new Set();
15
+ const boundChildren = new Set();
16
+ const bindingInFlight = new Map();
17
+ let reconciliationInFlight;
18
+ let reconciliationAgain = false;
19
+ const publish = () => {
20
+ revision += 1;
21
+ recoverySnapshot = { revision, pending: [...pending.values()] };
22
+ for (const subscriber of subscribers)
23
+ subscriber();
24
+ };
25
+ const setRecovery = (sourceSessionId, childSessionId, error, target) => {
26
+ if (disposed)
27
+ return;
28
+ const key = recoveryKey(sourceSessionId, childSessionId);
29
+ pending = new Map(pending).set(key, {
30
+ key,
31
+ sourceSessionId,
32
+ childSessionId,
33
+ ...(target === undefined ? {} : { binding: target }),
34
+ error,
35
+ });
36
+ publish();
37
+ };
38
+ const clearRecovery = (sourceSessionId, childSessionId) => {
39
+ const key = recoveryKey(sourceSessionId, childSessionId);
40
+ if (!pending.has(key))
41
+ return;
42
+ const next = new Map(pending);
43
+ next.delete(key);
44
+ pending = next;
45
+ publish();
46
+ };
47
+ const attemptBinding = async (sourceSessionId, childSessionId) => {
48
+ if (disposed || boundChildren.has(childSessionId))
49
+ return { bound: false };
50
+ let target;
51
+ try {
52
+ target = await options.findBinding(sourceSessionId);
53
+ }
54
+ catch (error) {
55
+ setRecovery(sourceSessionId, childSessionId, error);
56
+ return { bound: false };
57
+ }
58
+ if (disposed)
59
+ return { bound: false };
60
+ if (target === undefined || target.status !== 'active') {
61
+ clearRecovery(sourceSessionId, childSessionId);
62
+ return { bound: false };
63
+ }
64
+ try {
65
+ await options.bindSession({
66
+ workspaceId: target.workspaceId,
67
+ worktreeId: target.worktreeId,
68
+ sessionId: childSessionId,
69
+ });
70
+ if (disposed)
71
+ return { bound: false };
72
+ const childBinding = {
73
+ workspaceId: target.workspaceId,
74
+ worktreeId: target.worktreeId,
75
+ sessionId: childSessionId,
76
+ status: 'active',
77
+ };
78
+ boundChildren.add(childSessionId);
79
+ clearRecovery(sourceSessionId, childSessionId);
80
+ options.onBound?.(childBinding);
81
+ publish();
82
+ return { bound: true };
83
+ }
84
+ catch (error) {
85
+ setRecovery(sourceSessionId, childSessionId, error, target);
86
+ return { bound: false };
87
+ }
88
+ };
89
+ const bindChild = (sourceSessionId, childSessionId) => {
90
+ if (disposed || boundChildren.has(childSessionId)) {
91
+ return Promise.resolve({ bound: false });
92
+ }
93
+ const key = recoveryKey(sourceSessionId, childSessionId);
94
+ const current = bindingInFlight.get(key);
95
+ if (current !== undefined)
96
+ return current;
97
+ const promise = attemptBinding(sourceSessionId, childSessionId).finally(() => {
98
+ if (bindingInFlight.get(key) === promise)
99
+ bindingInFlight.delete(key);
100
+ });
101
+ bindingInFlight.set(key, promise);
102
+ return promise;
103
+ };
104
+ const reconcileNow = async () => {
105
+ if (disposed || options.sessions === undefined)
106
+ return;
107
+ const snapshot = options.sessions.getSnapshot();
108
+ if (snapshot.phase === 'pending')
109
+ return;
110
+ if (!Array.isArray(snapshot.ids) || typeof snapshot.byId !== 'object' || snapshot.byId === null) {
111
+ return;
112
+ }
113
+ const candidates = snapshot.ids.flatMap((childSessionId) => {
114
+ const summary = snapshot.byId[childSessionId];
115
+ if (summary?.parentId === undefined ||
116
+ summary.parentId === childSessionId ||
117
+ summary.blank === true ||
118
+ summary.origin === 'subagent' ||
119
+ snapshot.byId[summary.parentId] === undefined) {
120
+ return [];
121
+ }
122
+ return [{ childSessionId, sourceSessionId: summary.parentId }];
123
+ });
124
+ await Promise.all(candidates.map(({ childSessionId, sourceSessionId }) => bindChild(sourceSessionId, childSessionId).then(() => undefined)));
125
+ };
126
+ const reconcile = () => {
127
+ if (reconciliationInFlight !== undefined) {
128
+ reconciliationAgain = true;
129
+ return reconciliationInFlight;
130
+ }
131
+ const run = async () => {
132
+ do {
133
+ reconciliationAgain = false;
134
+ await reconcileNow();
135
+ } while (!disposed && reconciliationAgain);
136
+ };
137
+ const promise = run().finally(() => {
138
+ if (reconciliationInFlight === promise)
139
+ reconciliationInFlight = undefined;
140
+ });
141
+ reconciliationInFlight = promise;
142
+ return promise;
143
+ };
144
+ return {
145
+ recovery: {
146
+ getSnapshot() {
147
+ return recoverySnapshot;
148
+ },
149
+ subscribe(listener) {
150
+ subscribers.add(listener);
151
+ return () => subscribers.delete(listener);
152
+ },
153
+ },
154
+ async fork(input) {
155
+ const childSessionId = await options.fork(input);
156
+ if (!disposed)
157
+ await bindChild(input.sessionId, childSessionId);
158
+ return childSessionId;
159
+ },
160
+ reconcile,
161
+ async retry(key) {
162
+ const item = pending.get(key);
163
+ if (item === undefined || disposed)
164
+ return false;
165
+ return (await bindChild(item.sourceSessionId, item.childSessionId)).bound;
166
+ },
167
+ dispose() {
168
+ disposed = true;
169
+ bindingInFlight.clear();
170
+ subscribers.clear();
171
+ },
172
+ };
173
+ }
174
+ //# sourceMappingURL=worktree-session-fork.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-session-fork.js","sourceRoot":"","sources":["../../src/client/worktree-session-fork.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { createSnapshotStore as runtimeCreateSnapshotStore, SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client';
2
+ /** Browser-only persistence key; this state never crosses the DSH or sidecar boundary. */
3
+ export declare const WORKTREE_SESSION_ORDER_STORAGE_KEY = "clutch-dsh-worktree.session-order";
4
+ export interface SessionOrderAccountState {
5
+ order: string[];
6
+ observedUpdatedAt: Record<string, number>;
7
+ }
8
+ export interface WorktreeSessionOrderState {
9
+ accounts: Record<string, SessionOrderAccountState>;
10
+ }
11
+ export interface WorktreeSessionOrderActions {
12
+ reconcile: (accountKey: string, baseIds: readonly string[], updatedAtById: Readonly<Record<string, number | undefined>>) => void;
13
+ setOrder: (accountKey: string, order: readonly string[]) => void;
14
+ retain: (accountKeys: readonly string[]) => void;
15
+ }
16
+ export interface WorktreeSessionOrderStore extends SnapshotStore<WorktreeSessionOrderState> {
17
+ readonly actions: WorktreeSessionOrderActions;
18
+ readonly dispose: () => void;
19
+ }
20
+ export type SnapshotStoreFactory = typeof runtimeCreateSnapshotStore;
21
+ /** Normalize persisted state without trusting any browser-local JSON shape. */
22
+ export declare function normalizeWorktreeSessionOrderState(value: unknown): WorktreeSessionOrderState;
23
+ /**
24
+ * Native-style activity order transition. The first observation records timestamps
25
+ * without turning an existing list into a recency sort.
26
+ */
27
+ export declare function nextSessionOrderAccount(input: {
28
+ readonly baseIds: readonly string[];
29
+ readonly updatedAtById: Readonly<Record<string, number | undefined>>;
30
+ readonly previous?: Readonly<SessionOrderAccountState>;
31
+ }): SessionOrderAccountState;
32
+ /** Apply a successful manual drag without dropping IDs hidden by search. */
33
+ export declare function reorderSessionIds(order: readonly string[], sessionId: string, overSessionId: string, half: 'before' | 'after'): string[];
34
+ /** Create one apply-scoped, browser-local Session ordering store. */
35
+ export declare function createWorktreeSessionOrderStore(snapshotStoreFactory: SnapshotStoreFactory): WorktreeSessionOrderStore;
36
+ //# sourceMappingURL=worktree-session-order.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-session-order.d.ts","sourceRoot":"","sources":["../../src/client/worktree-session-order.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,IAAI,0BAA0B,EACjD,aAAa,EACd,MAAM,wCAAwC,CAAC;AAEhD,0FAA0F;AAC1F,eAAO,MAAM,kCAAkC,sCAAsC,CAAC;AAEtF,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,CACT,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,KACxD,IAAI,CAAC;IACV,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;IACjE,MAAM,EAAE,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;CAClD;AAED,MAAM,WAAW,yBAA0B,SAAQ,aAAa,CAAC,yBAAyB,CAAC;IACzF,QAAQ,CAAC,OAAO,EAAE,2BAA2B,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,MAAM,MAAM,oBAAoB,GAAG,OAAO,0BAA0B,CAAC;AAuCrE,+EAA+E;AAC/E,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,OAAO,GAAG,yBAAyB,CAS5F;AA6BD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,wBAAwB,CAAC,CAAC;CACxD,GAAG,wBAAwB,CA4D3B;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,QAAQ,GAAG,OAAO,GACvB,MAAM,EAAE,CAMV;AASD,qEAAqE;AACrE,wBAAgB,+BAA+B,CAC7C,oBAAoB,EAAE,oBAAoB,GACzC,yBAAyB,CAyD3B"}
@@ -0,0 +1,215 @@
1
+ /** Browser-only persistence key; this state never crosses the DSH or sidecar boundary. */
2
+ export const WORKTREE_SESSION_ORDER_STORAGE_KEY = 'clutch-dsh-worktree.session-order';
3
+ function emptyState() {
4
+ return { accounts: {} };
5
+ }
6
+ function isRecord(value) {
7
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
8
+ }
9
+ function isValidTimestamp(value) {
10
+ return typeof value === 'number' && Number.isFinite(value);
11
+ }
12
+ function normalizeIds(value) {
13
+ if (!Array.isArray(value))
14
+ return [];
15
+ const seen = new Set();
16
+ const ids = [];
17
+ for (const id of value) {
18
+ if (typeof id !== 'string' || id.length === 0 || seen.has(id))
19
+ continue;
20
+ seen.add(id);
21
+ ids.push(id);
22
+ }
23
+ return ids;
24
+ }
25
+ function normalizeAccount(value) {
26
+ if (!isRecord(value))
27
+ return undefined;
28
+ const order = normalizeIds(value.order);
29
+ const allowed = new Set(order);
30
+ const observedUpdatedAt = {};
31
+ if (isRecord(value.observedUpdatedAt)) {
32
+ for (const [id, timestamp] of Object.entries(value.observedUpdatedAt)) {
33
+ if (allowed.has(id) && isValidTimestamp(timestamp))
34
+ observedUpdatedAt[id] = timestamp;
35
+ }
36
+ }
37
+ return { order, observedUpdatedAt };
38
+ }
39
+ /** Normalize persisted state without trusting any browser-local JSON shape. */
40
+ export function normalizeWorktreeSessionOrderState(value) {
41
+ if (!isRecord(value) || !isRecord(value.accounts))
42
+ return emptyState();
43
+ const accounts = {};
44
+ for (const [accountKey, account] of Object.entries(value.accounts)) {
45
+ if (accountKey.length === 0)
46
+ continue;
47
+ const normalized = normalizeAccount(account);
48
+ if (normalized !== undefined)
49
+ accounts[accountKey] = normalized;
50
+ }
51
+ return { accounts };
52
+ }
53
+ function validIds(ids) {
54
+ return normalizeIds([...ids]);
55
+ }
56
+ function sameRecord(left, right) {
57
+ if (left === undefined)
58
+ return false;
59
+ const leftKeys = Object.keys(left);
60
+ const rightKeys = Object.keys(right);
61
+ if (leftKeys.length !== rightKeys.length)
62
+ return false;
63
+ return rightKeys.every((key) => left[key] === right[key]);
64
+ }
65
+ function sameAccount(left, right) {
66
+ return (left !== undefined &&
67
+ left.order.length === right.order.length &&
68
+ left.order.every((id, index) => id === right.order[index]) &&
69
+ sameRecord(left.observedUpdatedAt, right.observedUpdatedAt));
70
+ }
71
+ /**
72
+ * Native-style activity order transition. The first observation records timestamps
73
+ * without turning an existing list into a recency sort.
74
+ */
75
+ export function nextSessionOrderAccount(input) {
76
+ const baseIds = validIds(input.baseIds);
77
+ const previous = input.previous;
78
+ if (previous === undefined) {
79
+ const observedUpdatedAt = {};
80
+ for (const id of baseIds) {
81
+ const timestamp = input.updatedAtById[id];
82
+ if (isValidTimestamp(timestamp))
83
+ observedUpdatedAt[id] = timestamp;
84
+ }
85
+ return { order: baseIds, observedUpdatedAt };
86
+ }
87
+ const available = new Set(baseIds);
88
+ const order = [];
89
+ const seen = new Set();
90
+ for (const id of previous.order) {
91
+ if (available.has(id) && !seen.has(id)) {
92
+ seen.add(id);
93
+ order.push(id);
94
+ }
95
+ }
96
+ for (const id of baseIds) {
97
+ if (!seen.has(id)) {
98
+ seen.add(id);
99
+ order.push(id);
100
+ }
101
+ }
102
+ const observedUpdatedAt = {};
103
+ const previousIds = new Set(previous.order);
104
+ const newlyObserved = [];
105
+ const promoted = [];
106
+ for (const [index, id] of order.entries()) {
107
+ if (!previousIds.has(id))
108
+ newlyObserved.push(id);
109
+ const previousTimestamp = previous.observedUpdatedAt[id];
110
+ const timestamp = input.updatedAtById[id];
111
+ if (isValidTimestamp(previousTimestamp))
112
+ observedUpdatedAt[id] = previousTimestamp;
113
+ if (isValidTimestamp(timestamp)) {
114
+ if (!isValidTimestamp(previousTimestamp) || timestamp > previousTimestamp) {
115
+ if (isValidTimestamp(previousTimestamp)) {
116
+ promoted.push({ id, timestamp, index });
117
+ }
118
+ observedUpdatedAt[id] = Math.max(observedUpdatedAt[id] ?? timestamp, timestamp);
119
+ }
120
+ }
121
+ }
122
+ promoted.sort((left, right) => right.timestamp - left.timestamp || left.index - right.index);
123
+ const promotedIds = new Set([
124
+ ...newlyObserved,
125
+ ...promoted.map(({ id }) => id),
126
+ ]);
127
+ return {
128
+ order: [
129
+ ...newlyObserved,
130
+ ...promoted.map(({ id }) => id),
131
+ ...order.filter((id) => !promotedIds.has(id)),
132
+ ],
133
+ observedUpdatedAt,
134
+ };
135
+ }
136
+ /** Apply a successful manual drag without dropping IDs hidden by search. */
137
+ export function reorderSessionIds(order, sessionId, overSessionId, half) {
138
+ const next = order.filter((id) => id !== sessionId);
139
+ const targetIndex = next.indexOf(overSessionId);
140
+ if (targetIndex === -1)
141
+ return [...order];
142
+ next.splice(half === 'before' ? targetIndex : targetIndex + 1, 0, sessionId);
143
+ return next;
144
+ }
145
+ function cloneAccount(account) {
146
+ return {
147
+ order: [...account.order],
148
+ observedUpdatedAt: { ...account.observedUpdatedAt },
149
+ };
150
+ }
151
+ /** Create one apply-scoped, browser-local Session ordering store. */
152
+ export function createWorktreeSessionOrderStore(snapshotStoreFactory) {
153
+ let store;
154
+ try {
155
+ store = snapshotStoreFactory(emptyState(), {
156
+ persist: { name: WORKTREE_SESSION_ORDER_STORAGE_KEY },
157
+ });
158
+ }
159
+ catch {
160
+ store = snapshotStoreFactory(emptyState());
161
+ }
162
+ store.set(normalizeWorktreeSessionOrderState(store.getSnapshot()));
163
+ let disposed = false;
164
+ const actions = {
165
+ reconcile: (accountKey, baseIds, updatedAtById) => {
166
+ if (disposed || accountKey.length === 0)
167
+ return;
168
+ store.update((draft) => {
169
+ const next = nextSessionOrderAccount({
170
+ baseIds,
171
+ updatedAtById,
172
+ previous: draft.accounts[accountKey],
173
+ });
174
+ if (sameAccount(draft.accounts[accountKey], next))
175
+ return;
176
+ draft.accounts[accountKey] = cloneAccount(next);
177
+ });
178
+ },
179
+ setOrder: (accountKey, order) => {
180
+ if (disposed || accountKey.length === 0)
181
+ return;
182
+ store.update((draft) => {
183
+ const current = draft.accounts[accountKey] ?? {
184
+ order: [],
185
+ observedUpdatedAt: {},
186
+ };
187
+ const next = {
188
+ order: validIds(order),
189
+ observedUpdatedAt: { ...current.observedUpdatedAt },
190
+ };
191
+ if (sameAccount(current, next))
192
+ return;
193
+ draft.accounts[accountKey] = next;
194
+ });
195
+ },
196
+ retain: (accountKeys) => {
197
+ if (disposed)
198
+ return;
199
+ store.update((draft) => {
200
+ const allowed = new Set(accountKeys);
201
+ for (const accountKey of Object.keys(draft.accounts)) {
202
+ if (!allowed.has(accountKey))
203
+ delete draft.accounts[accountKey];
204
+ }
205
+ });
206
+ },
207
+ };
208
+ return Object.assign(store, {
209
+ actions,
210
+ dispose: () => {
211
+ disposed = true;
212
+ },
213
+ });
214
+ }
215
+ //# sourceMappingURL=worktree-session-order.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-session-order.js","sourceRoot":"","sources":["../../src/client/worktree-session-order.ts"],"names":[],"mappings":"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"}