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.
Files changed (39) hide show
  1. package/dist/board/boardRenderer.d.ts.map +1 -1
  2. package/dist/board/boardRenderer.js +26 -2
  3. package/dist/board/boardRenderer.js.map +1 -1
  4. package/dist/board/boardRoutes.d.ts +1 -1
  5. package/dist/board/boardRoutes.d.ts.map +1 -1
  6. package/dist/board/boardRoutes.js +63 -4
  7. package/dist/board/boardRoutes.js.map +1 -1
  8. package/dist/board/boardStyles.d.ts +1 -1
  9. package/dist/board/boardStyles.d.ts.map +1 -1
  10. package/dist/board/boardStyles.js +19 -8
  11. package/dist/board/boardStyles.js.map +1 -1
  12. package/dist/board/client/board.js +472 -136
  13. package/dist/cli/commands/export.d.ts +7 -0
  14. package/dist/cli/commands/export.d.ts.map +1 -0
  15. package/dist/cli/commands/export.js +30 -0
  16. package/dist/cli/commands/export.js.map +1 -0
  17. package/dist/cli/commands/import.d.ts +7 -0
  18. package/dist/cli/commands/import.d.ts.map +1 -0
  19. package/dist/cli/commands/import.js +44 -0
  20. package/dist/cli/commands/import.js.map +1 -0
  21. package/dist/cli/index.js +6 -0
  22. package/dist/cli/index.js.map +1 -1
  23. package/dist/services/ExportImportService.d.ts +84 -0
  24. package/dist/services/ExportImportService.d.ts.map +1 -0
  25. package/dist/services/ExportImportService.js +222 -0
  26. package/dist/services/ExportImportService.js.map +1 -0
  27. package/dist/services/ProcessService.d.ts +54 -0
  28. package/dist/services/ProcessService.d.ts.map +1 -0
  29. package/dist/services/ProcessService.js +147 -0
  30. package/dist/services/ProcessService.js.map +1 -0
  31. package/dist/services/TmuxService.d.ts +2 -0
  32. package/dist/services/TmuxService.d.ts.map +1 -0
  33. package/dist/services/TmuxService.js +7 -0
  34. package/dist/services/TmuxService.js.map +1 -0
  35. package/dist/services/index.d.ts +2 -0
  36. package/dist/services/index.d.ts.map +1 -1
  37. package/dist/services/index.js +3 -1
  38. package/dist/services/index.js.map +1 -1
  39. 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,2 @@
1
+ export { ProcessService as TmuxService, type TmuxSessionInfo } from './ProcessService';
2
+ //# sourceMappingURL=TmuxService.d.ts.map
@@ -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"}
@@ -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"}
@@ -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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agkan",
3
- "version": "2.13.0",
3
+ "version": "2.14.0",
4
4
  "description": "TypeScript-based CLI task management tool with SQLite storage",
5
5
  "main": "dist/cli/index.js",
6
6
  "bin": {