agkan 2.13.0 → 2.14.0
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/dist/board/boardRenderer.d.ts.map +1 -1
- package/dist/board/boardRenderer.js +26 -2
- package/dist/board/boardRenderer.js.map +1 -1
- package/dist/board/boardRoutes.d.ts +1 -1
- package/dist/board/boardRoutes.d.ts.map +1 -1
- package/dist/board/boardRoutes.js +63 -4
- package/dist/board/boardRoutes.js.map +1 -1
- package/dist/board/boardStyles.d.ts +1 -1
- package/dist/board/boardStyles.d.ts.map +1 -1
- package/dist/board/boardStyles.js +19 -8
- package/dist/board/boardStyles.js.map +1 -1
- package/dist/board/client/board.js +472 -136
- package/dist/cli/commands/export.d.ts +7 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +30 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/import.d.ts +7 -0
- package/dist/cli/commands/import.d.ts.map +1 -0
- package/dist/cli/commands/import.js +44 -0
- package/dist/cli/commands/import.js.map +1 -0
- package/dist/cli/index.js +6 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/services/ExportImportService.d.ts +84 -0
- package/dist/services/ExportImportService.d.ts.map +1 -0
- package/dist/services/ExportImportService.js +222 -0
- package/dist/services/ExportImportService.js.map +1 -0
- package/dist/services/ProcessService.d.ts +54 -0
- package/dist/services/ProcessService.d.ts.map +1 -0
- package/dist/services/ProcessService.js +147 -0
- package/dist/services/ProcessService.js.map +1 -0
- package/dist/services/TmuxService.d.ts +2 -0
- package/dist/services/TmuxService.d.ts.map +1 -0
- package/dist/services/TmuxService.js +7 -0
- package/dist/services/TmuxService.js.map +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +3 -1
- package/dist/services/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProcessService = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
/**
|
|
6
|
+
* Service for managing tmux sessions using child_process.spawn.
|
|
7
|
+
* Avoids zombie processes by using native Node.js APIs with spawn for tmux sessions.
|
|
8
|
+
* Properly handles process reaping in Docker containers by using:
|
|
9
|
+
* - spawn with detached=true for session creation (allows proper signal handling)
|
|
10
|
+
* - execSync for query operations (tmux commands that don't spawn long-lived processes)
|
|
11
|
+
*
|
|
12
|
+
* The key fix: tmux new-session is spawned with detached=true so it becomes
|
|
13
|
+
* a child of init, preventing zombie processes when the Node.js container doesn't
|
|
14
|
+
* have a proper init system.
|
|
15
|
+
*/
|
|
16
|
+
class ProcessService {
|
|
17
|
+
/**
|
|
18
|
+
* Start a new tmux session running the given command.
|
|
19
|
+
* Uses spawn with detached=true to prevent zombie processes in Docker.
|
|
20
|
+
* Throws if a session with the same name already exists (double-start prevention).
|
|
21
|
+
*/
|
|
22
|
+
startSession(sessionName, command) {
|
|
23
|
+
if (this.sessionExists(sessionName)) {
|
|
24
|
+
throw new Error(`Session '${sessionName}' already exists`);
|
|
25
|
+
}
|
|
26
|
+
// Use spawn with detached=true and stdio 'ignore' for proper process management
|
|
27
|
+
// This allows the tmux server to become a child of init rather than Node.js,
|
|
28
|
+
// preventing zombie processes when Node.js doesn't reap children
|
|
29
|
+
const child = (0, child_process_1.spawn)('tmux', ['new-session', '-d', '-s', sessionName, command], {
|
|
30
|
+
stdio: 'ignore',
|
|
31
|
+
detached: true,
|
|
32
|
+
});
|
|
33
|
+
// Immediately unref so Node.js doesn't wait for this process
|
|
34
|
+
child.unref();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Kill an existing tmux session.
|
|
38
|
+
*/
|
|
39
|
+
killSession(sessionName) {
|
|
40
|
+
try {
|
|
41
|
+
(0, child_process_1.execSync)(`tmux kill-session -t ${shellEscape(sessionName)}`, { stdio: 'pipe' });
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Session might not exist, that's fine
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* List all tmux sessions.
|
|
49
|
+
* Returns an empty array when no tmux server is running.
|
|
50
|
+
*/
|
|
51
|
+
listSessions() {
|
|
52
|
+
try {
|
|
53
|
+
const output = (0, child_process_1.execSync)("tmux list-sessions -F '#{session_name}|#{session_created_string}|#{session_windows}|#{session_attached}'", { stdio: 'pipe' })
|
|
54
|
+
.toString()
|
|
55
|
+
.trim();
|
|
56
|
+
if (!output)
|
|
57
|
+
return [];
|
|
58
|
+
return output.split('\n').map((line) => {
|
|
59
|
+
const [name, created, windows, attached] = line.split('|');
|
|
60
|
+
return { name, created, windows, attached };
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// No server running or no sessions
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Check whether a session with the given name currently exists.
|
|
70
|
+
*/
|
|
71
|
+
sessionExists(sessionName) {
|
|
72
|
+
try {
|
|
73
|
+
(0, child_process_1.execSync)(`tmux has-session -t ${shellEscape(sessionName)}`, { stdio: 'pipe' });
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Capture the visible pane content of a tmux session.
|
|
82
|
+
* Returns the captured text, or null when the session does not exist.
|
|
83
|
+
*/
|
|
84
|
+
capturePane(sessionName, lines = 500) {
|
|
85
|
+
if (!this.sessionExists(sessionName)) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const output = (0, child_process_1.execSync)(`tmux capture-pane -pt ${shellEscape(sessionName)} -S -${lines}`, {
|
|
90
|
+
stdio: 'pipe',
|
|
91
|
+
}).toString();
|
|
92
|
+
return output;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Asynchronously stream pane content at regular intervals.
|
|
100
|
+
* Calls onData with each captured snapshot and onEnd when the session exits.
|
|
101
|
+
* Returns a stop function to cancel polling.
|
|
102
|
+
*/
|
|
103
|
+
streamPane(sessionName, onData, onEnd, intervalMs = 500) {
|
|
104
|
+
let lastContent = '';
|
|
105
|
+
let stopped = false;
|
|
106
|
+
const poll = () => {
|
|
107
|
+
if (stopped)
|
|
108
|
+
return;
|
|
109
|
+
if (!this.sessionExists(sessionName)) {
|
|
110
|
+
onEnd();
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const content = this.capturePane(sessionName);
|
|
114
|
+
if (content !== null && content !== lastContent) {
|
|
115
|
+
lastContent = content;
|
|
116
|
+
onData(content);
|
|
117
|
+
}
|
|
118
|
+
setTimeout(poll, intervalMs);
|
|
119
|
+
};
|
|
120
|
+
setTimeout(poll, 0);
|
|
121
|
+
return () => {
|
|
122
|
+
stopped = true;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Send a key sequence to a tmux session pane.
|
|
127
|
+
*/
|
|
128
|
+
sendKeys(sessionName, keys) {
|
|
129
|
+
try {
|
|
130
|
+
(0, child_process_1.execSync)(`tmux send-keys -t ${shellEscape(sessionName)} ${shellEscape(keys)} Enter`, {
|
|
131
|
+
stdio: 'pipe',
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// Session might have ended
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.ProcessService = ProcessService;
|
|
140
|
+
/**
|
|
141
|
+
* Minimal shell escaping: wraps value in single quotes and escapes embedded single quotes.
|
|
142
|
+
* Suitable for passing arguments to tmux commands.
|
|
143
|
+
*/
|
|
144
|
+
function shellEscape(value) {
|
|
145
|
+
return "'" + value.replace(/'/g, "'\\''") + "'";
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=ProcessService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProcessService.js","sourceRoot":"","sources":["../../src/services/ProcessService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TmuxService.d.ts","sourceRoot":"","sources":["../../src/services/TmuxService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,IAAI,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TmuxService = void 0;
|
|
4
|
+
// Re-export ProcessService as TmuxService for backward compatibility
|
|
5
|
+
var ProcessService_1 = require("./ProcessService");
|
|
6
|
+
Object.defineProperty(exports, "TmuxService", { enumerable: true, get: function () { return ProcessService_1.ProcessService; } });
|
|
7
|
+
//# sourceMappingURL=TmuxService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TmuxService.js","sourceRoot":"","sources":["../../src/services/TmuxService.ts"],"names":[],"mappings":";;;AAAA,qEAAqE;AACrE,mDAAuF;AAA9E,6GAAA,cAAc,OAAe"}
|
package/dist/services/index.d.ts
CHANGED
|
@@ -9,4 +9,6 @@ export { TagService } from './TagService';
|
|
|
9
9
|
export { TaskTagService } from './TaskTagService';
|
|
10
10
|
export { MetadataService } from './MetadataService';
|
|
11
11
|
export { CommentService } from './CommentService';
|
|
12
|
+
export { ExportImportService } from './ExportImportService';
|
|
13
|
+
export type { ExportData, ExportedTask, ExportedComment, ImportResult } from './ExportImportService';
|
|
12
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/services/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Centrally manages all service classes
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.CommentService = exports.MetadataService = exports.TaskTagService = exports.TagService = exports.TaskBlockService = exports.FileService = exports.TaskService = void 0;
|
|
7
|
+
exports.ExportImportService = exports.CommentService = exports.MetadataService = exports.TaskTagService = exports.TagService = exports.TaskBlockService = exports.FileService = exports.TaskService = void 0;
|
|
8
8
|
var TaskService_1 = require("./TaskService");
|
|
9
9
|
Object.defineProperty(exports, "TaskService", { enumerable: true, get: function () { return TaskService_1.TaskService; } });
|
|
10
10
|
var FileService_1 = require("./FileService");
|
|
@@ -19,4 +19,6 @@ var MetadataService_1 = require("./MetadataService");
|
|
|
19
19
|
Object.defineProperty(exports, "MetadataService", { enumerable: true, get: function () { return MetadataService_1.MetadataService; } });
|
|
20
20
|
var CommentService_1 = require("./CommentService");
|
|
21
21
|
Object.defineProperty(exports, "CommentService", { enumerable: true, get: function () { return CommentService_1.CommentService; } });
|
|
22
|
+
var ExportImportService_1 = require("./ExportImportService");
|
|
23
|
+
Object.defineProperty(exports, "ExportImportService", { enumerable: true, get: function () { return ExportImportService_1.ExportImportService; } });
|
|
22
24
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AACzB,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,qDAAoD;AAA3C,kHAAA,eAAe,OAAA;AACxB,mDAAkD;AAAzC,gHAAA,cAAc,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AACzB,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,qDAAoD;AAA3C,kHAAA,eAAe,OAAA;AACxB,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,6DAA4D;AAAnD,0HAAA,mBAAmB,OAAA"}
|