github-issue-tower-defence-management 1.101.0 → 1.101.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.
- package/CHANGELOG.md +7 -0
- package/bin/adapter/repositories/NodeTmuxSessionRepository.js +1 -0
- package/bin/adapter/repositories/NodeTmuxSessionRepository.js.map +1 -1
- package/bin/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.js +9 -1
- package/bin/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.js.map +1 -1
- package/package.json +1 -1
- package/src/adapter/entry-points/handlers/inTmuxByHumanSessionReconciler.test.ts +3 -2
- package/src/adapter/repositories/NodeTmuxSessionRepository.test.ts +4 -3
- package/src/adapter/repositories/NodeTmuxSessionRepository.ts +1 -0
- package/src/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.test.ts +2 -2
- package/src/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.ts +9 -1
- package/types/adapter/repositories/NodeTmuxSessionRepository.d.ts.map +1 -1
- package/types/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [1.101.1](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.101.0...v1.101.1) (2026-06-25)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **intmux:** match tmux session name to app and attach-or-create to avoid duplicate sessions ([#949](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/949)) ([cf0208b](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/cf0208b956ba9abad8057e731d52fe917c8f5889))
|
|
7
|
+
|
|
1
8
|
# [1.101.0](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.100.0...v1.101.0) (2026-06-25)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeTmuxSessionRepository.js","sourceRoot":"","sources":["../../../src/adapter/repositories/NodeTmuxSessionRepository.ts"],"names":[],"mappings":";;;AAGA,MAAa,yBAAyB;IACpC,YAA6B,kBAAsC;QAAtC,uBAAkB,GAAlB,kBAAkB,CAAoB;QAEnE,yBAAoB,GAAG,KAAK,IAAuB,EAAE;YACnD,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CACnE,MAAM,EACN,CAAC,eAAe,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAC3C,CAAC;YACF,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACnB,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,MAAM;iBACV,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;iBAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC;QAEF,uCAAkC,GAAG,KAAK,IAAuB,EAAE;YACjE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CACnE,IAAI,EACJ,CAAC,KAAK,EAAE,OAAO,CAAC,CACjB,CAAC;YACF,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACnB,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,MAAM;iBACV,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;iBAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC;QAEF,0BAAqB,GAAG,KAAK,EAC3B,WAAmB,EACnB,eAAuB,EACvB,QAAgB,EACD,EAAE;YACjB,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,MAAM,EAAE;gBAC/C,aAAa;gBACb,IAAI;gBACJ,IAAI;gBACJ,WAAW;gBACX,IAAI;gBACJ,KAAK;gBACL,gBAAgB;gBAChB,IAAI;gBACJ,eAAe;gBACf,QAAQ;aACT,CAAC,CAAC;QACL,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"NodeTmuxSessionRepository.js","sourceRoot":"","sources":["../../../src/adapter/repositories/NodeTmuxSessionRepository.ts"],"names":[],"mappings":";;;AAGA,MAAa,yBAAyB;IACpC,YAA6B,kBAAsC;QAAtC,uBAAkB,GAAlB,kBAAkB,CAAoB;QAEnE,yBAAoB,GAAG,KAAK,IAAuB,EAAE;YACnD,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CACnE,MAAM,EACN,CAAC,eAAe,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAC3C,CAAC;YACF,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACnB,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,MAAM;iBACV,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;iBAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC;QAEF,uCAAkC,GAAG,KAAK,IAAuB,EAAE;YACjE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CACnE,IAAI,EACJ,CAAC,KAAK,EAAE,OAAO,CAAC,CACjB,CAAC;YACF,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACnB,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,MAAM;iBACV,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;iBAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC;QAEF,0BAAqB,GAAG,KAAK,EAC3B,WAAmB,EACnB,eAAuB,EACvB,QAAgB,EACD,EAAE;YACjB,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,MAAM,EAAE;gBAC/C,aAAa;gBACb,IAAI;gBACJ,IAAI;gBACJ,IAAI;gBACJ,WAAW;gBACX,IAAI;gBACJ,KAAK;gBACL,gBAAgB;gBAChB,IAAI;gBACJ,eAAe;gBACf,QAAQ;aACT,CAAC,CAAC;QACL,CAAC,CAAC;IAhDoE,CAAC;CAiDxE;AAlDD,8DAkDC"}
|
|
@@ -2,7 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InTmuxByHumanSessionReconcileUseCase = exports.toTmuxSessionName = void 0;
|
|
4
4
|
const WorkflowStatus_1 = require("../../entities/WorkflowStatus");
|
|
5
|
-
|
|
5
|
+
// tmux sanitizes a requested session name by replacing only `.` and `:` with
|
|
6
|
+
// `_`, while keeping every other character (including `/`). The Termux app
|
|
7
|
+
// launches each agent with `tmux new -A -s {ISSUE_URL}`, so tmux derives the
|
|
8
|
+
// authoritative session name from the raw issue URL. This function MUST return
|
|
9
|
+
// exactly that derived name so the reconciler recognizes the app's existing
|
|
10
|
+
// session instead of creating a duplicate under a differently-normalized name.
|
|
11
|
+
// For example `https://github.com/owner/repo/issues/9` becomes
|
|
12
|
+
// `https_//github_com/owner/repo/issues/9`.
|
|
13
|
+
const toTmuxSessionName = (issueUrl) => issueUrl.replace(/[.:]/g, '_');
|
|
6
14
|
exports.toTmuxSessionName = toTmuxSessionName;
|
|
7
15
|
class InTmuxByHumanSessionReconcileUseCase {
|
|
8
16
|
constructor(tmuxSessionRepository) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InTmuxByHumanSessionReconcileUseCase.js","sourceRoot":"","sources":["../../../../src/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.ts"],"names":[],"mappings":";;;AACA,kEAAoE;
|
|
1
|
+
{"version":3,"file":"InTmuxByHumanSessionReconcileUseCase.js","sourceRoot":"","sources":["../../../../src/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.ts"],"names":[],"mappings":";;;AACA,kEAAoE;AAapE,6EAA6E;AAC7E,2EAA2E;AAC3E,6EAA6E;AAC7E,+EAA+E;AAC/E,4EAA4E;AAC5E,+EAA+E;AAC/E,+DAA+D;AAC/D,4CAA4C;AACrC,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAU,EAAE,CAC5D,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AADpB,QAAA,iBAAiB,qBACG;AAEjC,MAAa,oCAAoC;IAC/C,YAA6B,qBAA4C;QAA5C,0BAAqB,GAArB,qBAAqB,CAAuB;QAEzE,QAAG,GAAG,KAAK,EACT,KAAyC,EACK,EAAE;YAChD,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC;YAEzD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAC3C,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,aAAa,CAAC,CAC3C,CAAC;YACF,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC9B,OAAO,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAC;YACnC,CAAC;YAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAC9B,MAAM,IAAI,CAAC,qBAAqB,CAAC,oBAAoB,EAAE,CACxD,CAAC;YACF,MAAM,mBAAmB,GACvB,MAAM,IAAI,CAAC,qBAAqB,CAAC,kCAAkC,EAAE,CAAC;YAExE,MAAM,iBAAiB,GAAa,EAAE,CAAC;YACvC,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;gBACjC,IACE,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,EAAE,gBAAgB,EAAE,mBAAmB,CAAC,EACrE,CAAC;oBACD,SAAS;gBACX,CAAC;gBACD,MAAM,IAAI,CAAC,qBAAqB,CAAC,qBAAqB,CACpD,IAAA,yBAAiB,EAAC,KAAK,CAAC,GAAG,CAAC,EAC5B,eAAe,EACf,KAAK,CAAC,GAAG,CACV,CAAC;gBACF,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACpC,CAAC;YAED,OAAO,EAAE,iBAAiB,EAAE,CAAC;QAC/B,CAAC,CAAC;QAEM,oBAAe,GAAG,CAAC,KAAY,EAAE,aAAqB,EAAW,EAAE,CACzE,KAAK,CAAC,MAAM,KAAK,oCAAmB;YACpC,KAAK,CAAC,QAAQ,KAAK,KAAK;YACxB,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAElC,mBAAc,GAAG,CACvB,QAAgB,EAChB,gBAA6B,EAC7B,mBAA6B,EACpB,EAAE;YACX,MAAM,WAAW,GAAG,IAAA,yBAAiB,EAAC,QAAQ,CAAC,CAAC;YAChD,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;gBACvC,OAAO,KAAK,CAAC;YACf,CAAC;YACD,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAC9C,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC/B,CAAC;QACJ,CAAC,CAAC;IAvD0E,CAAC;CAwD9E;AAzDD,oFAyDC"}
|
package/package.json
CHANGED
|
@@ -76,9 +76,10 @@ describe('reconcileInTmuxByHumanSessions', () => {
|
|
|
76
76
|
expect(newSessionCall).toBeDefined();
|
|
77
77
|
expect(newSessionCall?.[1]).toEqual([
|
|
78
78
|
'new-session',
|
|
79
|
+
'-A',
|
|
79
80
|
'-d',
|
|
80
81
|
'-s',
|
|
81
|
-
'
|
|
82
|
+
'https_//github_com/demo/repo/issues/1',
|
|
82
83
|
'sh',
|
|
83
84
|
'-lc',
|
|
84
85
|
'exec "$1" "$2"',
|
|
@@ -93,7 +94,7 @@ describe('reconcileInTmuxByHumanSessions', () => {
|
|
|
93
94
|
runner.runCommand.mockImplementation(async (program, args) => {
|
|
94
95
|
if (program === 'tmux' && args[0] === 'list-sessions') {
|
|
95
96
|
return {
|
|
96
|
-
stdout: '
|
|
97
|
+
stdout: 'https_//github_com/demo/repo/issues/1\n',
|
|
97
98
|
stderr: '',
|
|
98
99
|
exitCode: 0,
|
|
99
100
|
};
|
|
@@ -67,7 +67,7 @@ describe('NodeTmuxSessionRepository', () => {
|
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
describe('launchDetachedSession', () => {
|
|
70
|
-
it('creates a detached tmux session running the launcher command with the issue url', async () => {
|
|
70
|
+
it('attaches-or-creates a detached tmux session running the launcher command with the issue url', async () => {
|
|
71
71
|
const runner = createMockRunner();
|
|
72
72
|
runner.runCommand.mockResolvedValue({
|
|
73
73
|
stdout: '',
|
|
@@ -77,7 +77,7 @@ describe('NodeTmuxSessionRepository', () => {
|
|
|
77
77
|
const repository = new NodeTmuxSessionRepository(runner);
|
|
78
78
|
|
|
79
79
|
await repository.launchDetachedSession(
|
|
80
|
-
'
|
|
80
|
+
'https_//github_com/demo/repo/issues/1',
|
|
81
81
|
'cl',
|
|
82
82
|
'https://github.com/demo/repo/issues/1',
|
|
83
83
|
);
|
|
@@ -85,9 +85,10 @@ describe('NodeTmuxSessionRepository', () => {
|
|
|
85
85
|
expect(runner.runCommand.mock.calls[0][0]).toBe('tmux');
|
|
86
86
|
expect(runner.runCommand.mock.calls[0][1]).toEqual([
|
|
87
87
|
'new-session',
|
|
88
|
+
'-A',
|
|
88
89
|
'-d',
|
|
89
90
|
'-s',
|
|
90
|
-
'
|
|
91
|
+
'https_//github_com/demo/repo/issues/1',
|
|
91
92
|
'sh',
|
|
92
93
|
'-lc',
|
|
93
94
|
'exec "$1" "$2"',
|
|
@@ -178,9 +178,9 @@ describe('InTmuxByHumanSessionReconcileUseCase', () => {
|
|
|
178
178
|
expect(result.launchedIssueUrls).toEqual([]);
|
|
179
179
|
});
|
|
180
180
|
|
|
181
|
-
it('transforms an issue url into
|
|
181
|
+
it('transforms an issue url into the same session name tmux derives from the raw url, replacing only "." and ":" and keeping "/"', () => {
|
|
182
182
|
expect(toTmuxSessionName('https://github.com/demo/repo/issues/42')).toBe(
|
|
183
|
-
'
|
|
183
|
+
'https_//github_com/demo/repo/issues/42',
|
|
184
184
|
);
|
|
185
185
|
});
|
|
186
186
|
});
|
|
@@ -12,8 +12,16 @@ export type InTmuxByHumanSessionReconcileResult = {
|
|
|
12
12
|
launchedIssueUrls: string[];
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
+
// tmux sanitizes a requested session name by replacing only `.` and `:` with
|
|
16
|
+
// `_`, while keeping every other character (including `/`). The Termux app
|
|
17
|
+
// launches each agent with `tmux new -A -s {ISSUE_URL}`, so tmux derives the
|
|
18
|
+
// authoritative session name from the raw issue URL. This function MUST return
|
|
19
|
+
// exactly that derived name so the reconciler recognizes the app's existing
|
|
20
|
+
// session instead of creating a duplicate under a differently-normalized name.
|
|
21
|
+
// For example `https://github.com/owner/repo/issues/9` becomes
|
|
22
|
+
// `https_//github_com/owner/repo/issues/9`.
|
|
15
23
|
export const toTmuxSessionName = (issueUrl: string): string =>
|
|
16
|
-
issueUrl.replace(/[
|
|
24
|
+
issueUrl.replace(/[.:]/g, '_');
|
|
17
25
|
|
|
18
26
|
export class InTmuxByHumanSessionReconcileUseCase {
|
|
19
27
|
constructor(private readonly tmuxSessionRepository: TmuxSessionRepository) {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeTmuxSessionRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/NodeTmuxSessionRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6DAA6D,CAAC;AACjG,OAAO,EAAE,qBAAqB,EAAE,MAAM,gEAAgE,CAAC;AAEvG,qBAAa,yBAA0B,YAAW,qBAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,kBAAkB;gBAAlB,kBAAkB,EAAE,kBAAkB;IAEnE,oBAAoB,QAAa,OAAO,CAAC,MAAM,EAAE,CAAC,CAYhD;IAEF,kCAAkC,QAAa,OAAO,CAAC,MAAM,EAAE,CAAC,CAY9D;IAEF,qBAAqB,GACnB,aAAa,MAAM,EACnB,iBAAiB,MAAM,EACvB,UAAU,MAAM,KACf,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"NodeTmuxSessionRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/NodeTmuxSessionRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6DAA6D,CAAC;AACjG,OAAO,EAAE,qBAAqB,EAAE,MAAM,gEAAgE,CAAC;AAEvG,qBAAa,yBAA0B,YAAW,qBAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,kBAAkB;gBAAlB,kBAAkB,EAAE,kBAAkB;IAEnE,oBAAoB,QAAa,OAAO,CAAC,MAAM,EAAE,CAAC,CAYhD;IAEF,kCAAkC,QAAa,OAAO,CAAC,MAAM,EAAE,CAAC,CAY9D;IAEF,qBAAqB,GACnB,aAAa,MAAM,EACnB,iBAAiB,MAAM,EACvB,UAAU,MAAM,KACf,OAAO,CAAC,IAAI,CAAC,CAcd;CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InTmuxByHumanSessionReconcileUseCase.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AAEpF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,mCAAmC,GAAG;IAChD,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B,CAAC;
|
|
1
|
+
{"version":3,"file":"InTmuxByHumanSessionReconcileUseCase.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AAEpF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,mCAAmC,GAAG;IAChD,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B,CAAC;AAUF,eAAO,MAAM,iBAAiB,GAAI,UAAU,MAAM,KAAG,MACrB,CAAC;AAEjC,qBAAa,oCAAoC;IACnC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;gBAArB,qBAAqB,EAAE,qBAAqB;IAEzE,GAAG,GACD,OAAO,kCAAkC,KACxC,OAAO,CAAC,mCAAmC,CAAC,CAgC7C;IAEF,OAAO,CAAC,eAAe,CAGmB;IAE1C,OAAO,CAAC,cAAc,CAYpB;CACH"}
|