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,7 @@
1
+ /**
2
+ * Export command handler
3
+ * Outputs all task data as JSON to stdout
4
+ */
5
+ import { Command } from 'commander';
6
+ export declare function setupExportCommand(program: Command): void;
7
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/export.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkBzD"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ /**
3
+ * Export command handler
4
+ * Outputs all task data as JSON to stdout
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.setupExportCommand = setupExportCommand;
8
+ const ExportImportService_1 = require("../../services/ExportImportService");
9
+ function setupExportCommand(program) {
10
+ program
11
+ .command('export')
12
+ .description('Export all tasks to JSON format (pipe to file: agkan export > backup.json)')
13
+ .action(() => {
14
+ try {
15
+ const service = new ExportImportService_1.ExportImportService();
16
+ const data = service.exportData();
17
+ process.stdout.write(JSON.stringify(data, null, 2) + '\n');
18
+ }
19
+ catch (error) {
20
+ if (error instanceof Error) {
21
+ process.stderr.write(`Error: ${error.message}\n`);
22
+ }
23
+ else {
24
+ process.stderr.write('An unknown error occurred\n');
25
+ }
26
+ process.exit(1);
27
+ }
28
+ });
29
+ }
30
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../../src/cli/commands/export.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAKH,gDAkBC;AApBD,4EAAyE;AAEzE,SAAgB,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,4EAA4E,CAAC;SACzF,MAAM,CAAC,GAAG,EAAE;QACX,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,yCAAmB,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;YAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YACtD,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Import command handler
3
+ * Reads a JSON file and imports all task data
4
+ */
5
+ import { Command } from 'commander';
6
+ export declare function setupImportCommand(program: Command): void;
7
+ //# sourceMappingURL=import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/import.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgCzD"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ /**
3
+ * Import command handler
4
+ * Reads a JSON file and imports all task data
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.setupImportCommand = setupImportCommand;
8
+ const fs_1 = require("fs");
9
+ const ExportImportService_1 = require("../../services/ExportImportService");
10
+ function setupImportCommand(program) {
11
+ program
12
+ .command('import <file>')
13
+ .description('Import tasks from a JSON export file')
14
+ .action((file) => {
15
+ try {
16
+ const content = (0, fs_1.readFileSync)(file, 'utf8');
17
+ let data;
18
+ try {
19
+ data = JSON.parse(content);
20
+ }
21
+ catch {
22
+ process.stderr.write('Error: Invalid JSON file\n');
23
+ process.exit(1);
24
+ }
25
+ if (!data.tasks || !Array.isArray(data.tasks)) {
26
+ process.stderr.write('Error: Invalid export file format (missing tasks array)\n');
27
+ process.exit(1);
28
+ }
29
+ const service = new ExportImportService_1.ExportImportService();
30
+ const result = service.importData(data);
31
+ process.stdout.write(`Imported ${result.importedCount} task(s) successfully.\n`);
32
+ }
33
+ catch (error) {
34
+ if (error instanceof Error) {
35
+ process.stderr.write(`Error: ${error.message}\n`);
36
+ }
37
+ else {
38
+ process.stderr.write('An unknown error occurred\n');
39
+ }
40
+ process.exit(1);
41
+ }
42
+ });
43
+ }
44
+ //# sourceMappingURL=import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.js","sourceRoot":"","sources":["../../../src/cli/commands/import.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAMH,gDAgCC;AAnCD,2BAAkC;AAClC,4EAAqF;AAErF,SAAgB,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,sCAAsC,CAAC;SACnD,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;QACvB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAA,iBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC3C,IAAI,IAAgB,CAAC;YACrB,IAAI,CAAC;gBACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAe,CAAC;YAC3C,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;gBACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;gBAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,yCAAmB,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM,CAAC,aAAa,0BAA0B,CAAC,CAAC;QACnF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YACtD,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
package/dist/cli/index.js CHANGED
@@ -41,6 +41,9 @@ const board_1 = require("./commands/board");
41
41
  const agent_guide_1 = require("./commands/agent-guide");
42
42
  // Init command handler
43
43
  const init_1 = require("./commands/init");
44
+ // Export/Import command handlers
45
+ const export_1 = require("./commands/export");
46
+ const import_1 = require("./commands/import");
44
47
  const program = new commander_1.Command();
45
48
  // Load version from package.json
46
49
  const packageJson = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../../package.json'), 'utf8'));
@@ -87,6 +90,9 @@ program.command('tag').description('Tag management commands');
87
90
  (0, agent_guide_1.setupAgentGuideCommand)(program);
88
91
  // Register init command
89
92
  (0, init_1.setupInitCommand)(program);
93
+ // Register export/import commands
94
+ (0, export_1.setupExportCommand)(program);
95
+ (0, import_1.setupImportCommand)(program);
90
96
  // Execute program
91
97
  program.parse(process.argv);
92
98
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import { StorageProvider } from '../db/types/storage';
2
+ export interface ExportedComment {
3
+ author: string | null;
4
+ content: string;
5
+ created_at: string;
6
+ updated_at: string;
7
+ }
8
+ export interface ExportedTask {
9
+ id: number;
10
+ title: string;
11
+ body: string | null;
12
+ author: string | null;
13
+ assignees: string | null;
14
+ status: string;
15
+ parent_id: number | null;
16
+ created_at: string;
17
+ updated_at: string;
18
+ tags: string[];
19
+ metadata: Record<string, string>;
20
+ comments: ExportedComment[];
21
+ blocked_by: number[];
22
+ }
23
+ export interface ExportData {
24
+ version: string;
25
+ exported_at: string;
26
+ tasks: ExportedTask[];
27
+ }
28
+ export interface ImportResult {
29
+ importedCount: number;
30
+ idMapping: Map<number, number>;
31
+ }
32
+ /**
33
+ * Export/Import Service
34
+ * Handles JSON bulk export and import of tasks with all related data
35
+ */
36
+ export declare class ExportImportService {
37
+ private db;
38
+ private taskService;
39
+ private tagService;
40
+ private taskTagService;
41
+ private metadataService;
42
+ private commentService;
43
+ private taskBlockService;
44
+ constructor(db?: StorageProvider);
45
+ /**
46
+ * Build a map from task_id to list of blocker task IDs
47
+ */
48
+ private buildBlockedByMap;
49
+ /**
50
+ * Export all tasks with related data as JSON
51
+ * @returns Export data object with version, timestamp, and tasks
52
+ */
53
+ exportData(): ExportData;
54
+ /**
55
+ * Import a single task and restore its timestamps
56
+ */
57
+ private importTask;
58
+ /**
59
+ * Add tags to a task, creating tags that don't yet exist
60
+ */
61
+ private importTaskTags;
62
+ /**
63
+ * Add comments to a task, restoring original timestamps
64
+ */
65
+ private importTaskComments;
66
+ /**
67
+ * Create block relationships for all tasks using remapped IDs
68
+ */
69
+ private importBlockRelationships;
70
+ /**
71
+ * Import tasks from exported JSON data
72
+ * Resolves parent_id and blocked_by using old->new ID mapping
73
+ * Preserves original created_at/updated_at timestamps
74
+ * Auto-creates tags if not found by name
75
+ * @param data - Export data to import
76
+ * @returns Import result with count and ID mapping
77
+ */
78
+ importData(data: ExportData): ImportResult;
79
+ /**
80
+ * Sort tasks so parents come before children (topological sort)
81
+ */
82
+ private sortTasksByParent;
83
+ }
84
+ //# sourceMappingURL=ExportImportService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportImportService.d.ts","sourceRoot":"","sources":["../../src/services/ExportImportService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAQtD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,gBAAgB,CAAmB;gBAE/B,EAAE,CAAC,EAAE,eAAe;IAUhC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;;OAGG;IACH,UAAU,IAAI,UAAU;IA8CxB;;OAEG;IACH,OAAO,CAAC,UAAU;IAoBlB;;OAEG;IACH,OAAO,CAAC,cAAc;IActB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAoBhC;;;;;;;OAOG;IACH,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,YAAY;IAyB1C;;OAEG;IACH,OAAO,CAAC,iBAAiB;CA2B1B"}
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExportImportService = void 0;
4
+ const connection_1 = require("../db/connection");
5
+ const TaskService_1 = require("./TaskService");
6
+ const TagService_1 = require("./TagService");
7
+ const TaskTagService_1 = require("./TaskTagService");
8
+ const MetadataService_1 = require("./MetadataService");
9
+ const CommentService_1 = require("./CommentService");
10
+ const TaskBlockService_1 = require("./TaskBlockService");
11
+ /**
12
+ * Export/Import Service
13
+ * Handles JSON bulk export and import of tasks with all related data
14
+ */
15
+ class ExportImportService {
16
+ db;
17
+ taskService;
18
+ tagService;
19
+ taskTagService;
20
+ metadataService;
21
+ commentService;
22
+ taskBlockService;
23
+ constructor(db) {
24
+ this.db = db || (0, connection_1.getDatabase)();
25
+ this.taskService = new TaskService_1.TaskService(this.db);
26
+ this.tagService = new TagService_1.TagService(this.db);
27
+ this.taskTagService = new TaskTagService_1.TaskTagService(this.db);
28
+ this.metadataService = new MetadataService_1.MetadataService(this.db);
29
+ this.commentService = new CommentService_1.CommentService(this.db);
30
+ this.taskBlockService = new TaskBlockService_1.TaskBlockService(this.db);
31
+ }
32
+ /**
33
+ * Build a map from task_id to list of blocker task IDs
34
+ */
35
+ buildBlockedByMap() {
36
+ const blockedByMap = new Map();
37
+ for (const block of this.taskBlockService.getAllBlocks()) {
38
+ const blockedId = block.blocked_task_id;
39
+ if (!blockedByMap.has(blockedId)) {
40
+ blockedByMap.set(blockedId, []);
41
+ }
42
+ blockedByMap.get(blockedId).push(block.blocker_task_id);
43
+ }
44
+ return blockedByMap;
45
+ }
46
+ /**
47
+ * Export all tasks with related data as JSON
48
+ * @returns Export data object with version, timestamp, and tasks
49
+ */
50
+ exportData() {
51
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
52
+ const { version } = require('../../package.json');
53
+ const tasks = this.taskService.listTasks({}, 'id', 'asc');
54
+ const allTaskTags = this.taskTagService.getAllTaskTags();
55
+ const allMetadata = this.metadataService.getAllTasksMetadata();
56
+ const allComments = this.commentService.getCommentsForTasks(tasks.map((t) => t.id));
57
+ const blockedByMap = this.buildBlockedByMap();
58
+ const exportedTasks = tasks.map((task) => {
59
+ const tags = (allTaskTags.get(task.id) || []).map((tag) => tag.name);
60
+ const metadataList = allMetadata.get(task.id) || [];
61
+ const metadata = {};
62
+ for (const m of metadataList) {
63
+ metadata[m.key] = m.value;
64
+ }
65
+ const comments = (allComments.get(task.id) || []).map((c) => ({
66
+ author: c.author,
67
+ content: c.content,
68
+ created_at: c.created_at,
69
+ updated_at: c.updated_at,
70
+ }));
71
+ return {
72
+ id: task.id,
73
+ title: task.title,
74
+ body: task.body,
75
+ author: task.author,
76
+ assignees: task.assignees,
77
+ status: task.status,
78
+ parent_id: task.parent_id,
79
+ created_at: task.created_at,
80
+ updated_at: task.updated_at,
81
+ tags,
82
+ metadata,
83
+ comments,
84
+ blocked_by: blockedByMap.get(task.id) || [],
85
+ };
86
+ });
87
+ return {
88
+ version,
89
+ exported_at: new Date().toISOString(),
90
+ tasks: exportedTasks,
91
+ };
92
+ }
93
+ /**
94
+ * Import a single task and restore its timestamps
95
+ */
96
+ importTask(exportedTask, idMapping) {
97
+ const newParentId = exportedTask.parent_id !== null ? (idMapping.get(exportedTask.parent_id) ?? null) : null;
98
+ const newTask = this.taskService.createTask({
99
+ title: exportedTask.title,
100
+ body: exportedTask.body || undefined,
101
+ author: exportedTask.author || undefined,
102
+ assignees: exportedTask.assignees || undefined,
103
+ status: exportedTask.status,
104
+ parent_id: newParentId,
105
+ });
106
+ // Restore original timestamps via direct UPDATE
107
+ this.db
108
+ .prepare('UPDATE tasks SET created_at = ?, updated_at = ? WHERE id = ?')
109
+ .run(exportedTask.created_at, exportedTask.updated_at, newTask.id);
110
+ return newTask.id;
111
+ }
112
+ /**
113
+ * Add tags to a task, creating tags that don't yet exist
114
+ */
115
+ importTaskTags(taskId, tagNames) {
116
+ for (const tagName of tagNames) {
117
+ let tag = this.tagService.getTagByName(tagName);
118
+ if (!tag) {
119
+ tag = this.tagService.createTag({ name: tagName });
120
+ }
121
+ try {
122
+ this.taskTagService.addTagToTask({ task_id: taskId, tag_id: tag.id });
123
+ }
124
+ catch {
125
+ // Tag already attached, skip
126
+ }
127
+ }
128
+ }
129
+ /**
130
+ * Add comments to a task, restoring original timestamps
131
+ */
132
+ importTaskComments(taskId, comments) {
133
+ for (const comment of comments) {
134
+ const newComment = this.commentService.addComment({
135
+ task_id: taskId,
136
+ author: comment.author || undefined,
137
+ content: comment.content,
138
+ });
139
+ this.db
140
+ .prepare('UPDATE task_comments SET created_at = ?, updated_at = ? WHERE id = ?')
141
+ .run(comment.created_at, comment.updated_at, newComment.id);
142
+ }
143
+ }
144
+ /**
145
+ * Create block relationships for all tasks using remapped IDs
146
+ */
147
+ importBlockRelationships(tasks, idMapping) {
148
+ for (const exportedTask of tasks) {
149
+ const newTaskId = idMapping.get(exportedTask.id);
150
+ if (newTaskId === undefined)
151
+ continue;
152
+ for (const oldBlockerId of exportedTask.blocked_by) {
153
+ const newBlockerId = idMapping.get(oldBlockerId);
154
+ if (newBlockerId === undefined)
155
+ continue;
156
+ try {
157
+ this.taskBlockService.addBlock({
158
+ blocker_task_id: newBlockerId,
159
+ blocked_task_id: newTaskId,
160
+ });
161
+ }
162
+ catch {
163
+ // Skip if circular or already exists
164
+ }
165
+ }
166
+ }
167
+ }
168
+ /**
169
+ * Import tasks from exported JSON data
170
+ * Resolves parent_id and blocked_by using old->new ID mapping
171
+ * Preserves original created_at/updated_at timestamps
172
+ * Auto-creates tags if not found by name
173
+ * @param data - Export data to import
174
+ * @returns Import result with count and ID mapping
175
+ */
176
+ importData(data) {
177
+ const idMapping = new Map();
178
+ const sortedTasks = this.sortTasksByParent(data.tasks);
179
+ for (const exportedTask of sortedTasks) {
180
+ const newTaskId = this.importTask(exportedTask, idMapping);
181
+ idMapping.set(exportedTask.id, newTaskId);
182
+ this.importTaskTags(newTaskId, exportedTask.tags);
183
+ for (const [key, value] of Object.entries(exportedTask.metadata)) {
184
+ this.metadataService.setMetadata({ task_id: newTaskId, key, value });
185
+ }
186
+ this.importTaskComments(newTaskId, exportedTask.comments);
187
+ }
188
+ this.importBlockRelationships(data.tasks, idMapping);
189
+ return {
190
+ importedCount: sortedTasks.length,
191
+ idMapping,
192
+ };
193
+ }
194
+ /**
195
+ * Sort tasks so parents come before children (topological sort)
196
+ */
197
+ sortTasksByParent(tasks) {
198
+ const taskMap = new Map();
199
+ for (const task of tasks) {
200
+ taskMap.set(task.id, task);
201
+ }
202
+ const sorted = [];
203
+ const visited = new Set();
204
+ const visit = (task) => {
205
+ if (visited.has(task.id))
206
+ return;
207
+ visited.add(task.id);
208
+ if (task.parent_id !== null) {
209
+ const parent = taskMap.get(task.parent_id);
210
+ if (parent)
211
+ visit(parent);
212
+ }
213
+ sorted.push(task);
214
+ };
215
+ for (const task of tasks) {
216
+ visit(task);
217
+ }
218
+ return sorted;
219
+ }
220
+ }
221
+ exports.ExportImportService = ExportImportService;
222
+ //# sourceMappingURL=ExportImportService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportImportService.js","sourceRoot":"","sources":["../../src/services/ExportImportService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ export interface TmuxSessionInfo {
2
+ name: string;
3
+ created: string;
4
+ windows: string;
5
+ attached: string;
6
+ }
7
+ /**
8
+ * Service for managing tmux sessions using child_process.spawn.
9
+ * Avoids zombie processes by using native Node.js APIs with spawn for tmux sessions.
10
+ * Properly handles process reaping in Docker containers by using:
11
+ * - spawn with detached=true for session creation (allows proper signal handling)
12
+ * - execSync for query operations (tmux commands that don't spawn long-lived processes)
13
+ *
14
+ * The key fix: tmux new-session is spawned with detached=true so it becomes
15
+ * a child of init, preventing zombie processes when the Node.js container doesn't
16
+ * have a proper init system.
17
+ */
18
+ export declare class ProcessService {
19
+ /**
20
+ * Start a new tmux session running the given command.
21
+ * Uses spawn with detached=true to prevent zombie processes in Docker.
22
+ * Throws if a session with the same name already exists (double-start prevention).
23
+ */
24
+ startSession(sessionName: string, command: string): void;
25
+ /**
26
+ * Kill an existing tmux session.
27
+ */
28
+ killSession(sessionName: string): void;
29
+ /**
30
+ * List all tmux sessions.
31
+ * Returns an empty array when no tmux server is running.
32
+ */
33
+ listSessions(): TmuxSessionInfo[];
34
+ /**
35
+ * Check whether a session with the given name currently exists.
36
+ */
37
+ sessionExists(sessionName: string): boolean;
38
+ /**
39
+ * Capture the visible pane content of a tmux session.
40
+ * Returns the captured text, or null when the session does not exist.
41
+ */
42
+ capturePane(sessionName: string, lines?: number): string | null;
43
+ /**
44
+ * Asynchronously stream pane content at regular intervals.
45
+ * Calls onData with each captured snapshot and onEnd when the session exits.
46
+ * Returns a stop function to cancel polling.
47
+ */
48
+ streamPane(sessionName: string, onData: (chunk: string) => void, onEnd: () => void, intervalMs?: number): () => void;
49
+ /**
50
+ * Send a key sequence to a tmux session pane.
51
+ */
52
+ sendKeys(sessionName: string, keys: string): void;
53
+ }
54
+ //# sourceMappingURL=ProcessService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProcessService.d.ts","sourceRoot":"","sources":["../../src/services/ProcessService.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,cAAc;IACzB;;;;OAIG;IACH,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAiBxD;;OAEG;IACH,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAQtC;;;OAGG;IACH,YAAY,IAAI,eAAe,EAAE;IAoBjC;;OAEG;IACH,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAS3C;;;OAGG;IACH,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,GAAE,MAAY,GAAG,MAAM,GAAG,IAAI;IAcpE;;;;OAIG;IACH,UAAU,CACR,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAC/B,KAAK,EAAE,MAAM,IAAI,EACjB,UAAU,GAAE,MAAY,GACvB,MAAM,IAAI;IA4Bb;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;CASlD"}