@assistkick/create 1.10.0 → 1.11.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/src/scaffolder.d.ts +12 -1
- package/dist/src/scaffolder.js +40 -3
- package/dist/src/scaffolder.js.map +1 -1
- package/package.json +1 -1
- package/templates/assistkick-product-system/package.json +1 -1
- package/templates/assistkick-product-system/packages/backend/package.json +1 -0
- package/templates/assistkick-product-system/packages/backend/src/mcp/permission_mcp_server.ts +196 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/agents.ts +31 -7
- package/templates/assistkick-product-system/packages/backend/src/routes/auth.ts +15 -12
- package/templates/assistkick-product-system/packages/backend/src/routes/chat_files.test.ts +95 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/chat_files.ts +97 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/chat_permission.ts +94 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/chat_sessions.ts +189 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/chat_upload.test.ts +131 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/chat_upload.ts +94 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/files.test.ts +12 -3
- package/templates/assistkick-product-system/packages/backend/src/routes/files.ts +2 -2
- package/templates/assistkick-product-system/packages/backend/src/routes/git.ts +390 -22
- package/templates/assistkick-product-system/packages/backend/src/routes/git_branches.test.ts +306 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/git_connect.test.ts +133 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/pipeline.ts +66 -9
- package/templates/assistkick-product-system/packages/backend/src/routes/preview.ts +204 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/projects.test.ts +205 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/projects.ts +37 -9
- package/templates/assistkick-product-system/packages/backend/src/routes/skills.test.ts +139 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/skills.ts +95 -0
- package/templates/assistkick-product-system/packages/backend/src/routes/terminal.ts +5 -4
- package/templates/assistkick-product-system/packages/backend/src/routes/users.ts +4 -4
- package/templates/assistkick-product-system/packages/backend/src/routes/video.ts +8 -8
- package/templates/assistkick-product-system/packages/backend/src/routes/workflow_groups.ts +5 -5
- package/templates/assistkick-product-system/packages/backend/src/routes/workflows.ts +6 -6
- package/templates/assistkick-product-system/packages/backend/src/server.ts +107 -27
- package/templates/assistkick-product-system/packages/backend/src/services/agent_service.test.ts +105 -203
- package/templates/assistkick-product-system/packages/backend/src/services/agent_service.ts +76 -266
- package/templates/assistkick-product-system/packages/backend/src/services/chat_cli_bridge.test.ts +427 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_cli_bridge.ts +345 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_message_repository.test.ts +170 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_message_repository.ts +106 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_session_service.test.ts +217 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_session_service.ts +188 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_ws_handler.test.ts +1243 -0
- package/templates/assistkick-product-system/packages/backend/src/services/chat_ws_handler.ts +894 -0
- package/templates/assistkick-product-system/packages/backend/src/services/coherence-review.ts +3 -3
- package/templates/assistkick-product-system/packages/backend/src/services/dev_command_detector.test.ts +85 -0
- package/templates/assistkick-product-system/packages/backend/src/services/dev_command_detector.ts +54 -0
- package/templates/assistkick-product-system/packages/backend/src/services/email_service.ts +13 -10
- package/templates/assistkick-product-system/packages/backend/src/services/init.ts +11 -3
- package/templates/assistkick-product-system/packages/backend/src/services/invitation_service.ts +1 -1
- package/templates/assistkick-product-system/packages/backend/src/services/password_reset_service.ts +1 -1
- package/templates/assistkick-product-system/packages/backend/src/services/permission_service.test.ts +243 -0
- package/templates/assistkick-product-system/packages/backend/src/services/permission_service.ts +259 -0
- package/templates/assistkick-product-system/packages/backend/src/services/preview_server_manager.test.ts +172 -0
- package/templates/assistkick-product-system/packages/backend/src/services/preview_server_manager.ts +225 -0
- package/templates/assistkick-product-system/packages/backend/src/services/project_service.test.ts +29 -0
- package/templates/assistkick-product-system/packages/backend/src/services/project_service.ts +17 -0
- package/templates/assistkick-product-system/packages/backend/src/services/project_workspace_service.test.ts +255 -0
- package/templates/assistkick-product-system/packages/backend/src/services/project_workspace_service.ts +300 -25
- package/templates/assistkick-product-system/packages/backend/src/services/pty_session_manager.test.ts +44 -0
- package/templates/assistkick-product-system/packages/backend/src/services/pty_session_manager.ts +62 -7
- package/templates/assistkick-product-system/packages/backend/src/services/ssh_key_service.test.ts +77 -6
- package/templates/assistkick-product-system/packages/backend/src/services/ssh_key_service.ts +129 -8
- package/templates/assistkick-product-system/packages/backend/src/services/terminal_ws_handler.ts +2 -1
- package/templates/assistkick-product-system/packages/backend/src/services/title_generator_service.test.ts +45 -0
- package/templates/assistkick-product-system/packages/backend/src/services/title_generator_service.ts +157 -0
- package/templates/assistkick-product-system/packages/backend/src/services/tts_service.ts +4 -3
- package/templates/assistkick-product-system/packages/backend/src/services/video_render_service.ts +3 -3
- package/templates/assistkick-product-system/packages/frontend/package.json +5 -0
- package/templates/assistkick-product-system/packages/frontend/src/App.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/api/client.ts +336 -5
- package/templates/assistkick-product-system/packages/frontend/src/components/AgentsView.tsx +192 -12
- package/templates/assistkick-product-system/packages/frontend/src/components/AttachmentPreviewList.tsx +98 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/AutocompleteDropdown.tsx +65 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatAttachButton.tsx +56 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatDropZone.tsx +80 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatMessageBubble.tsx +155 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatMessageContent.tsx +182 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatMessageInput.tsx +233 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatSessionSidebar.tsx +218 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatStopButton.tsx +32 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatTodoSidebar.tsx +113 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ChatView.tsx +842 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/CommitMessageModal.tsx +82 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/DiagramOverlay.tsx +160 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/EditorTabBar.tsx +5 -5
- package/templates/assistkick-product-system/packages/frontend/src/components/FileTree.tsx +9 -10
- package/templates/assistkick-product-system/packages/frontend/src/components/FileTreeInlineInput.tsx +5 -5
- package/templates/assistkick-product-system/packages/frontend/src/components/FilesView.tsx +112 -41
- package/templates/assistkick-product-system/packages/frontend/src/components/GraphLegend.tsx +2 -2
- package/templates/assistkick-product-system/packages/frontend/src/components/HighlightedText.tsx +87 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ImageLightbox.tsx +192 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/KanbanView.tsx +2 -2
- package/templates/assistkick-product-system/packages/frontend/src/components/MentionPill.tsx +33 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/MermaidBlock.tsx +148 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/PermissionDialog.tsx +91 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/PermissionModeSelector.tsx +229 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ProjectSelector.tsx +249 -83
- package/templates/assistkick-product-system/packages/frontend/src/components/QueuedMessageBubble.tsx +38 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/SidePanel.tsx +212 -117
- package/templates/assistkick-product-system/packages/frontend/src/components/SystemPromptAccordion.tsx +48 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/TaskIcon.tsx +11 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/TerminalView.tsx +25 -9
- package/templates/assistkick-product-system/packages/frontend/src/components/ToolDiffView.tsx +114 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ToolResultCard.tsx +87 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/ToolUseCard.tsx +149 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/Toolbar.tsx +25 -8
- package/templates/assistkick-product-system/packages/frontend/src/components/UnifiedGitWidget.tsx +722 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/GroupNode.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/NodePalette.tsx +2 -1
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/ProgrammableNode.tsx +178 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/WorkflowCanvas.tsx +3 -0
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/WorkflowMonitorModal.tsx +103 -9
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/monitor_nodes.tsx +26 -2
- package/templates/assistkick-product-system/packages/frontend/src/components/workflow/workflow_types.ts +42 -1
- package/templates/assistkick-product-system/packages/frontend/src/hooks/useDocumentTitle.ts +11 -0
- package/templates/assistkick-product-system/packages/frontend/src/hooks/useProjects.ts +1 -0
- package/templates/assistkick-product-system/packages/frontend/src/hooks/use_chat_stream.ts +826 -0
- package/templates/assistkick-product-system/packages/frontend/src/hooks/use_file_tree_cache.ts +69 -0
- package/templates/assistkick-product-system/packages/frontend/src/hooks/use_mention_autocomplete.ts +284 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/attachment_manager.test.ts +183 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/attachment_manager.ts +150 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/chat_message_helpers.test.ts +305 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/chat_message_helpers.ts +113 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/context_usage_helpers.test.ts +157 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/context_usage_helpers.ts +95 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/mermaid_helpers.test.ts +65 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/mermaid_helpers.ts +110 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/message_queue.ts +66 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/tool_use_summary.test.ts +124 -0
- package/templates/assistkick-product-system/packages/frontend/src/lib/tool_use_summary.ts +112 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/AgentsRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/ChatRoute.tsx +8 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/CoherenceRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/DashboardLayout.tsx +0 -4
- package/templates/assistkick-product-system/packages/frontend/src/routes/DesignSystemRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/FilesRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/GraphRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/KanbanRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/TerminalRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/UsersRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/VideographyRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/WorkflowsRoute.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/accept_invitation.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/forgot_password.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/login.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/register.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/routes/reset_password.tsx +2 -0
- package/templates/assistkick-product-system/packages/frontend/src/stores/useAttachmentStore.ts +66 -0
- package/templates/assistkick-product-system/packages/frontend/src/stores/useChatSessionStore.ts +107 -0
- package/templates/assistkick-product-system/packages/frontend/src/stores/useMessageQueueStore.ts +110 -0
- package/templates/assistkick-product-system/packages/frontend/src/stores/usePreviewStore.ts +78 -0
- package/templates/assistkick-product-system/packages/frontend/src/stores/useProjectStore.ts +7 -0
- package/templates/assistkick-product-system/packages/frontend/src/stores/useSidePanelStore.ts +6 -1
- package/templates/assistkick-product-system/packages/frontend/src/styles/index.css +30 -357
- package/templates/assistkick-product-system/packages/frontend/src/utils/parse_node_markdown.test.ts +115 -0
- package/templates/assistkick-product-system/packages/frontend/src/utils/parse_node_markdown.ts +91 -0
- package/templates/assistkick-product-system/packages/frontend/src/utils/preview_utils.test.ts +30 -0
- package/templates/assistkick-product-system/packages/frontend/src/utils/preview_utils.ts +3 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0015_magenta_jazinda.sql +1 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0016_giant_xorn.sql +1 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0017_sloppy_mentor.sql +6 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0018_vengeful_kabuki.sql +9 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0019_careful_sentinels.sql +8 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0020_clever_spot.sql +27 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0021_graceful_hex.sql +1 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0022_short_kingpin.sql +1 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0023_ambiguous_sharon_carter.sql +1 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/0024_fat_unus.sql +1 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0015_snapshot.json +1552 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0016_snapshot.json +1560 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0017_snapshot.json +1598 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0018_snapshot.json +1657 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0019_snapshot.json +1709 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0020_snapshot.json +1733 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0021_snapshot.json +1740 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0022_snapshot.json +1755 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0023_snapshot.json +1762 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0024_snapshot.json +1769 -0
- package/templates/assistkick-product-system/packages/shared/db/migrations/meta/_journal.json +70 -0
- package/templates/assistkick-product-system/packages/shared/db/schema.ts +40 -1
- package/templates/assistkick-product-system/packages/shared/lib/claude-service.test.ts +236 -0
- package/templates/assistkick-product-system/packages/shared/lib/claude-service.ts +46 -5
- package/templates/assistkick-product-system/packages/shared/lib/git_workflow.ts +65 -39
- package/templates/assistkick-product-system/packages/shared/lib/programmable_node_executor.test.ts +173 -0
- package/templates/assistkick-product-system/packages/shared/lib/programmable_node_executor.ts +213 -0
- package/templates/assistkick-product-system/packages/shared/lib/validator.test.ts +70 -0
- package/templates/assistkick-product-system/packages/shared/lib/validator.ts +17 -1
- package/templates/assistkick-product-system/packages/shared/lib/workflow_engine.test.ts +803 -27
- package/templates/assistkick-product-system/packages/shared/lib/workflow_engine.ts +502 -68
- package/templates/assistkick-product-system/packages/shared/lib/workflow_orchestrator.ts +4 -4
- package/templates/assistkick-product-system/packages/shared/package.json +2 -1
- package/templates/assistkick-product-system/packages/shared/test_fixtures/hanging_stream.mjs +46 -0
- package/templates/assistkick-product-system/packages/shared/tools/add_node.test.ts +44 -0
- package/templates/assistkick-product-system/packages/shared/tools/add_node.ts +7 -0
- package/templates/assistkick-product-system/packages/shared/tools/remove_node.ts +2 -1
- package/templates/assistkick-product-system/packages/shared/tools/resolve_question.ts +2 -1
- package/templates/assistkick-product-system/packages/shared/tools/update_node.ts +2 -1
- package/templates/assistkick-product-system/tests/message_queue.test.ts +178 -0
- package/templates/assistkick-product-system/tests/message_queue_per_session.test.ts +143 -0
- package/templates/skills/assistkick-bootstrap/SKILL.md +26 -26
- package/templates/skills/assistkick-code-reviewer/SKILL.md +45 -46
- package/templates/skills/assistkick-db-explorer/SKILL.md +13 -13
- package/templates/skills/assistkick-debugger/SKILL.md +23 -23
- package/templates/skills/assistkick-developer/SKILL.md +59 -63
- package/templates/skills/assistkick-interview/SKILL.md +26 -26
- package/templates/skills/assistkick-video-composition-agent/SKILL.md +231 -0
- package/templates/skills/assistkick-video-script-writer/SKILL.md +136 -0
|
@@ -55,7 +55,7 @@ export class WorkflowOrchestrator {
|
|
|
55
55
|
|
|
56
56
|
// Fire-and-forget — loop runs in the background
|
|
57
57
|
this.runLoop().catch(err => {
|
|
58
|
-
this.log('ORCHESTRATOR', `Play All UNCAUGHT ERROR
|
|
58
|
+
this.log('ORCHESTRATOR', `Play All UNCAUGHT ERROR:`, err.stack || err.message);
|
|
59
59
|
}).finally(() => {
|
|
60
60
|
this.active = false;
|
|
61
61
|
this.currentFeatureId = null;
|
|
@@ -100,7 +100,7 @@ export class WorkflowOrchestrator {
|
|
|
100
100
|
kanbanData = await this.loadKanban(this.projectId);
|
|
101
101
|
graphData = await this.readGraph(this.projectId);
|
|
102
102
|
} catch (err: any) {
|
|
103
|
-
this.log('ORCHESTRATOR', `Failed to fetch data
|
|
103
|
+
this.log('ORCHESTRATOR', `Failed to fetch data:`, err.stack || err.message);
|
|
104
104
|
break;
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -167,7 +167,7 @@ export class WorkflowOrchestrator {
|
|
|
167
167
|
try {
|
|
168
168
|
await this.workflowEngine.start(card.id, defaultWorkflow.id, this.projectId);
|
|
169
169
|
} catch (err: any) {
|
|
170
|
-
this.log('ORCHESTRATOR', `Failed to start workflow for ${card.id}
|
|
170
|
+
this.log('ORCHESTRATOR', `Failed to start workflow for ${card.id}:`, err.stack || err.message);
|
|
171
171
|
continue;
|
|
172
172
|
}
|
|
173
173
|
|
|
@@ -201,7 +201,7 @@ export class WorkflowOrchestrator {
|
|
|
201
201
|
return;
|
|
202
202
|
}
|
|
203
203
|
} catch (err: any) {
|
|
204
|
-
this.log('ORCHESTRATOR', `Error polling status for ${featureId}
|
|
204
|
+
this.log('ORCHESTRATOR', `Error polling status for ${featureId}:`, err.stack || err.message);
|
|
205
205
|
return;
|
|
206
206
|
}
|
|
207
207
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test fixture: simulates a Claude CLI process in stream-json mode
|
|
3
|
+
* that emits a result event but never exits (hangs).
|
|
4
|
+
* Used by claude-service tests to verify the post-result timeout.
|
|
5
|
+
*
|
|
6
|
+
* Usage: node hanging_stream.mjs [--exit-after-ms <ms>]
|
|
7
|
+
* No args: emits result event and hangs indefinitely
|
|
8
|
+
* --exit-after-ms <ms>: emits result event and exits normally after <ms> milliseconds
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Read stdin (prompt) to avoid broken pipe
|
|
12
|
+
process.stdin.resume();
|
|
13
|
+
process.stdin.on('data', () => {});
|
|
14
|
+
process.stdin.on('end', () => {});
|
|
15
|
+
|
|
16
|
+
// Emit an assistant event
|
|
17
|
+
const assistantEvent = JSON.stringify({
|
|
18
|
+
type: 'assistant',
|
|
19
|
+
message: {
|
|
20
|
+
content: [{ type: 'text', text: 'Implementation complete.' }],
|
|
21
|
+
usage: { input_tokens: 100, output_tokens: 50 },
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
process.stdout.write(assistantEvent + '\n');
|
|
25
|
+
|
|
26
|
+
// Emit a result event (this signals the conversation is complete)
|
|
27
|
+
const resultEvent = JSON.stringify({
|
|
28
|
+
type: 'result',
|
|
29
|
+
result: 'Test result output from the agent.',
|
|
30
|
+
cost_usd: 0.01,
|
|
31
|
+
duration_ms: 1234,
|
|
32
|
+
num_turns: 1,
|
|
33
|
+
stop_reason: 'end_turn',
|
|
34
|
+
model: 'claude-test',
|
|
35
|
+
});
|
|
36
|
+
process.stdout.write(resultEvent + '\n');
|
|
37
|
+
|
|
38
|
+
// Parse args
|
|
39
|
+
const exitAfterIdx = process.argv.indexOf('--exit-after-ms');
|
|
40
|
+
if (exitAfterIdx !== -1) {
|
|
41
|
+
const ms = parseInt(process.argv[exitAfterIdx + 1], 10);
|
|
42
|
+
setTimeout(() => process.exit(0), ms);
|
|
43
|
+
} else {
|
|
44
|
+
// Hang indefinitely — keep the event loop alive with a long timer
|
|
45
|
+
setInterval(() => {}, 60_000);
|
|
46
|
+
}
|
|
@@ -16,6 +16,25 @@ const deriveFeatureType = (
|
|
|
16
16
|
return null;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Determines whether a new node should be auto-added to the kanban backlog.
|
|
21
|
+
* Mirrors the logic in add_node.ts.
|
|
22
|
+
*/
|
|
23
|
+
const shouldAutoAddToKanban = (nodeType: string): boolean => {
|
|
24
|
+
return nodeType === 'feature';
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Builds the initial kanban entry for a newly created feature.
|
|
29
|
+
* Mirrors the entry shape passed to saveKanbanEntry in add_node.ts.
|
|
30
|
+
*/
|
|
31
|
+
const buildInitialKanbanEntry = () => ({
|
|
32
|
+
column: 'backlog',
|
|
33
|
+
rejection_count: 0,
|
|
34
|
+
notes: [],
|
|
35
|
+
reviews: [],
|
|
36
|
+
});
|
|
37
|
+
|
|
19
38
|
describe('deriveFeatureType', () => {
|
|
20
39
|
it('returns "video" for feature nodes in video projects', () => {
|
|
21
40
|
assert.equal(deriveFeatureType('feature', 'video'), 'video');
|
|
@@ -41,3 +60,28 @@ describe('deriveFeatureType', () => {
|
|
|
41
60
|
assert.equal(deriveFeatureType('decision', 'software'), null);
|
|
42
61
|
});
|
|
43
62
|
});
|
|
63
|
+
|
|
64
|
+
describe('shouldAutoAddToKanban', () => {
|
|
65
|
+
it('returns true for feature nodes', () => {
|
|
66
|
+
assert.equal(shouldAutoAddToKanban('feature'), true);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('returns false for non-feature node types', () => {
|
|
70
|
+
assert.equal(shouldAutoAddToKanban('component'), false);
|
|
71
|
+
assert.equal(shouldAutoAddToKanban('decision'), false);
|
|
72
|
+
assert.equal(shouldAutoAddToKanban('epic'), false);
|
|
73
|
+
assert.equal(shouldAutoAddToKanban('data_entity'), false);
|
|
74
|
+
assert.equal(shouldAutoAddToKanban('tech_choice'), false);
|
|
75
|
+
assert.equal(shouldAutoAddToKanban('non_functional_requirement'), false);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('buildInitialKanbanEntry', () => {
|
|
80
|
+
it('creates a backlog entry with zeroed counters', () => {
|
|
81
|
+
const entry = buildInitialKanbanEntry();
|
|
82
|
+
assert.equal(entry.column, 'backlog');
|
|
83
|
+
assert.equal(entry.rejection_count, 0);
|
|
84
|
+
assert.deepEqual(entry.notes, []);
|
|
85
|
+
assert.deepEqual(entry.reviews, []);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -14,6 +14,7 @@ import { getDb } from '../lib/db.js';
|
|
|
14
14
|
import { nodes, projects } from '../db/schema.js';
|
|
15
15
|
import { deriveMetadata, templateSections } from '../lib/markdown.js';
|
|
16
16
|
import { assertValidType, assertUniqueName } from '../lib/validator.js';
|
|
17
|
+
import { saveKanbanEntry } from '../lib/kanban.js';
|
|
17
18
|
|
|
18
19
|
program
|
|
19
20
|
.requiredOption('--type <type>', 'Node type (e.g., feature, component, decision)')
|
|
@@ -96,6 +97,12 @@ const opts = program.opts();
|
|
|
96
97
|
projectId: opts.projectId,
|
|
97
98
|
});
|
|
98
99
|
|
|
100
|
+
// Auto-add features to the kanban backlog
|
|
101
|
+
if (opts.type === 'feature') {
|
|
102
|
+
await saveKanbanEntry(id, { column: 'backlog', rejection_count: 0, notes: [], reviews: [] }, opts.projectId);
|
|
103
|
+
console.log(chalk.green(`✓ Added ${id} to kanban backlog`));
|
|
104
|
+
}
|
|
105
|
+
|
|
99
106
|
console.log(chalk.green(`✓ Created ${opts.type} node: ${id}`));
|
|
100
107
|
console.log(JSON.stringify({ id, type: opts.type, name: opts.name }));
|
|
101
108
|
} catch (err) {
|
|
@@ -10,7 +10,7 @@ import { eq, or } from 'drizzle-orm';
|
|
|
10
10
|
import { createInterface } from 'node:readline';
|
|
11
11
|
import { getDb } from '../lib/db.js';
|
|
12
12
|
import { getNode } from '../lib/graph.js';
|
|
13
|
-
import { assertNodeExists } from '../lib/validator.js';
|
|
13
|
+
import { assertNodeExists, assertNotDone } from '../lib/validator.js';
|
|
14
14
|
import { nodes, edges, kanban, reviewMeta } from '../db/schema.js';
|
|
15
15
|
|
|
16
16
|
program
|
|
@@ -35,6 +35,7 @@ const confirm = async (message: string): Promise<boolean> => {
|
|
|
35
35
|
(async () => {
|
|
36
36
|
try {
|
|
37
37
|
await assertNodeExists(id);
|
|
38
|
+
await assertNotDone(id);
|
|
38
39
|
|
|
39
40
|
const node = await getNode(id);
|
|
40
41
|
const db = getDb();
|
|
@@ -8,7 +8,7 @@ import { program } from 'commander';
|
|
|
8
8
|
import chalk from 'chalk';
|
|
9
9
|
import { readGraph, patchNode } from '../lib/graph.js';
|
|
10
10
|
import { readNode, writeNode, deriveMetadata } from '../lib/markdown.js';
|
|
11
|
-
import { assertNodeExists } from '../lib/validator.js';
|
|
11
|
+
import { assertNodeExists, assertNotDone } from '../lib/validator.js';
|
|
12
12
|
|
|
13
13
|
program
|
|
14
14
|
.argument('<id>', 'Node ID containing the question')
|
|
@@ -23,6 +23,7 @@ const opts = program.opts();
|
|
|
23
23
|
(async () => {
|
|
24
24
|
try {
|
|
25
25
|
await assertNodeExists(id);
|
|
26
|
+
await assertNotDone(id);
|
|
26
27
|
|
|
27
28
|
const graph = await readGraph();
|
|
28
29
|
const nodeMeta = graph.nodes.find(n => n.id === id);
|
|
@@ -8,7 +8,7 @@ import { program } from 'commander';
|
|
|
8
8
|
import chalk from 'chalk';
|
|
9
9
|
import { readGraph, patchNode } from '../lib/graph.js';
|
|
10
10
|
import { readNode, writeNode, appendToSection, setSection, deriveMetadata } from '../lib/markdown.js';
|
|
11
|
-
import { assertNodeExists } from '../lib/validator.js';
|
|
11
|
+
import { assertNodeExists, assertNotDone } from '../lib/validator.js';
|
|
12
12
|
import { VALID_STATUSES, VALID_PRIORITIES, VALID_FEATURE_KINDS } from '../lib/constants.js';
|
|
13
13
|
import { getKanbanEntry, saveKanbanEntry } from '../lib/kanban.js';
|
|
14
14
|
|
|
@@ -32,6 +32,7 @@ const opts = program.opts();
|
|
|
32
32
|
(async () => {
|
|
33
33
|
try {
|
|
34
34
|
await assertNodeExists(id);
|
|
35
|
+
await assertNotDone(id);
|
|
35
36
|
|
|
36
37
|
const graph = await readGraph();
|
|
37
38
|
const nodeMeta = graph.nodes.find(n => n.id === id);
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the Chat v2 Message Queue.
|
|
3
|
+
* Validates enqueue, remove, clear, drainAll, and mergeTexts operations.
|
|
4
|
+
* Uses node:test built-in runner.
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, beforeEach } from 'node:test';
|
|
7
|
+
import assert from 'node:assert/strict';
|
|
8
|
+
import { MessageQueue } from '../packages/frontend/src/lib/message_queue.ts';
|
|
9
|
+
|
|
10
|
+
describe('MessageQueue', () => {
|
|
11
|
+
let queue: MessageQueue;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
queue = new MessageQueue();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe('enqueue', () => {
|
|
18
|
+
it('adds a message to an empty queue', () => {
|
|
19
|
+
queue.enqueue('Hello');
|
|
20
|
+
|
|
21
|
+
assert.equal(queue.getLength(), 1);
|
|
22
|
+
assert.equal(queue.getQueue()[0].text, 'Hello');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('appends multiple messages in order', () => {
|
|
26
|
+
queue.enqueue('First');
|
|
27
|
+
queue.enqueue('Second');
|
|
28
|
+
queue.enqueue('Third');
|
|
29
|
+
|
|
30
|
+
const items = queue.getQueue();
|
|
31
|
+
assert.equal(items.length, 3);
|
|
32
|
+
assert.equal(items[0].text, 'First');
|
|
33
|
+
assert.equal(items[1].text, 'Second');
|
|
34
|
+
assert.equal(items[2].text, 'Third');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('generates unique IDs for each message', () => {
|
|
38
|
+
queue.enqueue('A');
|
|
39
|
+
queue.enqueue('B');
|
|
40
|
+
|
|
41
|
+
const items = queue.getQueue();
|
|
42
|
+
assert.notEqual(items[0].id, items[1].id);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('sets createdAt timestamp', () => {
|
|
46
|
+
const before = Date.now();
|
|
47
|
+
queue.enqueue('Test');
|
|
48
|
+
const after = Date.now();
|
|
49
|
+
|
|
50
|
+
const msg = queue.getQueue()[0];
|
|
51
|
+
assert.ok(msg.createdAt >= before);
|
|
52
|
+
assert.ok(msg.createdAt <= after);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('returns the enqueued message', () => {
|
|
56
|
+
const msg = queue.enqueue('Return me');
|
|
57
|
+
|
|
58
|
+
assert.equal(msg.text, 'Return me');
|
|
59
|
+
assert.ok(msg.id.startsWith('q_'));
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('remove', () => {
|
|
64
|
+
it('removes a specific message by id', () => {
|
|
65
|
+
queue.enqueue('Keep');
|
|
66
|
+
queue.enqueue('Remove me');
|
|
67
|
+
queue.enqueue('Also keep');
|
|
68
|
+
|
|
69
|
+
const removeId = queue.getQueue()[1].id;
|
|
70
|
+
const removed = queue.remove(removeId);
|
|
71
|
+
|
|
72
|
+
assert.equal(removed, true);
|
|
73
|
+
assert.equal(queue.getLength(), 2);
|
|
74
|
+
assert.equal(queue.getQueue()[0].text, 'Keep');
|
|
75
|
+
assert.equal(queue.getQueue()[1].text, 'Also keep');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('returns false when id does not exist', () => {
|
|
79
|
+
queue.enqueue('Only one');
|
|
80
|
+
|
|
81
|
+
const removed = queue.remove('nonexistent_id');
|
|
82
|
+
|
|
83
|
+
assert.equal(removed, false);
|
|
84
|
+
assert.equal(queue.getLength(), 1);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe('clear', () => {
|
|
89
|
+
it('removes all messages from the queue', () => {
|
|
90
|
+
queue.enqueue('One');
|
|
91
|
+
queue.enqueue('Two');
|
|
92
|
+
queue.enqueue('Three');
|
|
93
|
+
|
|
94
|
+
queue.clear();
|
|
95
|
+
|
|
96
|
+
assert.equal(queue.getLength(), 0);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('is safe to call on an empty queue', () => {
|
|
100
|
+
queue.clear();
|
|
101
|
+
|
|
102
|
+
assert.equal(queue.getLength(), 0);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe('drainAll', () => {
|
|
107
|
+
it('returns all messages and empties the queue', () => {
|
|
108
|
+
queue.enqueue('First');
|
|
109
|
+
queue.enqueue('Second');
|
|
110
|
+
|
|
111
|
+
const drained = queue.drainAll();
|
|
112
|
+
|
|
113
|
+
assert.equal(drained.length, 2);
|
|
114
|
+
assert.equal(drained[0].text, 'First');
|
|
115
|
+
assert.equal(drained[1].text, 'Second');
|
|
116
|
+
assert.equal(queue.getLength(), 0);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('returns empty array when queue is empty', () => {
|
|
120
|
+
const drained = queue.drainAll();
|
|
121
|
+
|
|
122
|
+
assert.equal(drained.length, 0);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('subsequent drain returns empty after first drain', () => {
|
|
126
|
+
queue.enqueue('Once');
|
|
127
|
+
|
|
128
|
+
const first = queue.drainAll();
|
|
129
|
+
const second = queue.drainAll();
|
|
130
|
+
|
|
131
|
+
assert.equal(first.length, 1);
|
|
132
|
+
assert.equal(second.length, 0);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe('mergeTexts', () => {
|
|
137
|
+
it('merges messages with double newline separator', () => {
|
|
138
|
+
queue.enqueue('Fix the bug in auth');
|
|
139
|
+
queue.enqueue('Also update the docs');
|
|
140
|
+
queue.enqueue('Run the tests when done');
|
|
141
|
+
|
|
142
|
+
const drained = queue.drainAll();
|
|
143
|
+
const merged = MessageQueue.mergeTexts(drained);
|
|
144
|
+
|
|
145
|
+
assert.equal(
|
|
146
|
+
merged,
|
|
147
|
+
'Fix the bug in auth\n\nAlso update the docs\n\nRun the tests when done',
|
|
148
|
+
);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('returns single message text without separator', () => {
|
|
152
|
+
queue.enqueue('Only one message');
|
|
153
|
+
|
|
154
|
+
const drained = queue.drainAll();
|
|
155
|
+
const merged = MessageQueue.mergeTexts(drained);
|
|
156
|
+
|
|
157
|
+
assert.equal(merged, 'Only one message');
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('returns empty string for empty array', () => {
|
|
161
|
+
const merged = MessageQueue.mergeTexts([]);
|
|
162
|
+
|
|
163
|
+
assert.equal(merged, '');
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
describe('getQueue immutability', () => {
|
|
168
|
+
it('returns a readonly snapshot that is not affected by later enqueues', () => {
|
|
169
|
+
queue.enqueue('Original');
|
|
170
|
+
const snapshot = queue.getQueue();
|
|
171
|
+
|
|
172
|
+
queue.enqueue('New');
|
|
173
|
+
|
|
174
|
+
assert.equal(snapshot.length, 1);
|
|
175
|
+
assert.equal(queue.getLength(), 2);
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
});
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for per-session message queue scoping.
|
|
3
|
+
*
|
|
4
|
+
* Validates that the MessageQueue class correctly isolates queues when used
|
|
5
|
+
* in a per-session Map pattern (as useMessageQueueStore does internally).
|
|
6
|
+
* Uses node:test built-in runner.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, beforeEach } from 'node:test';
|
|
9
|
+
import assert from 'node:assert/strict';
|
|
10
|
+
import { MessageQueue } from '../packages/frontend/src/lib/message_queue.ts';
|
|
11
|
+
|
|
12
|
+
describe('Per-session MessageQueue isolation', () => {
|
|
13
|
+
let sessionQueues: Map<string, MessageQueue>;
|
|
14
|
+
|
|
15
|
+
const getOrCreateQueue = (sessionId: string): MessageQueue => {
|
|
16
|
+
let mq = sessionQueues.get(sessionId);
|
|
17
|
+
if (!mq) {
|
|
18
|
+
mq = new MessageQueue();
|
|
19
|
+
sessionQueues.set(sessionId, mq);
|
|
20
|
+
}
|
|
21
|
+
return mq;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
sessionQueues = new Map();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('enqueues messages to separate sessions independently', () => {
|
|
29
|
+
const queueA = getOrCreateQueue('session_a');
|
|
30
|
+
const queueB = getOrCreateQueue('session_b');
|
|
31
|
+
|
|
32
|
+
queueA.enqueue('Message for A');
|
|
33
|
+
queueB.enqueue('Message for B');
|
|
34
|
+
queueA.enqueue('Second message for A');
|
|
35
|
+
|
|
36
|
+
assert.equal(queueA.getLength(), 2);
|
|
37
|
+
assert.equal(queueB.getLength(), 1);
|
|
38
|
+
assert.equal(queueA.getQueue()[0].text, 'Message for A');
|
|
39
|
+
assert.equal(queueB.getQueue()[0].text, 'Message for B');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('draining one session does not affect another', () => {
|
|
43
|
+
const queueA = getOrCreateQueue('session_a');
|
|
44
|
+
const queueB = getOrCreateQueue('session_b');
|
|
45
|
+
|
|
46
|
+
queueA.enqueue('A1');
|
|
47
|
+
queueA.enqueue('A2');
|
|
48
|
+
queueB.enqueue('B1');
|
|
49
|
+
|
|
50
|
+
const drained = queueA.drainAll();
|
|
51
|
+
|
|
52
|
+
assert.equal(drained.length, 2);
|
|
53
|
+
assert.equal(queueA.getLength(), 0);
|
|
54
|
+
assert.equal(queueB.getLength(), 1);
|
|
55
|
+
assert.equal(queueB.getQueue()[0].text, 'B1');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('clearing one session preserves the other', () => {
|
|
59
|
+
const queueA = getOrCreateQueue('session_a');
|
|
60
|
+
const queueB = getOrCreateQueue('session_b');
|
|
61
|
+
|
|
62
|
+
queueA.enqueue('A1');
|
|
63
|
+
queueB.enqueue('B1');
|
|
64
|
+
queueB.enqueue('B2');
|
|
65
|
+
|
|
66
|
+
queueA.clear();
|
|
67
|
+
|
|
68
|
+
assert.equal(queueA.getLength(), 0);
|
|
69
|
+
assert.equal(queueB.getLength(), 2);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('removing a message from one session does not affect another', () => {
|
|
73
|
+
const queueA = getOrCreateQueue('session_a');
|
|
74
|
+
const queueB = getOrCreateQueue('session_b');
|
|
75
|
+
|
|
76
|
+
const msgA = queueA.enqueue('A1');
|
|
77
|
+
queueB.enqueue('B1');
|
|
78
|
+
|
|
79
|
+
queueA.remove(msgA.id);
|
|
80
|
+
|
|
81
|
+
assert.equal(queueA.getLength(), 0);
|
|
82
|
+
assert.equal(queueB.getLength(), 1);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('switching active session shows correct queue', () => {
|
|
86
|
+
const queueA = getOrCreateQueue('session_a');
|
|
87
|
+
const queueB = getOrCreateQueue('session_b');
|
|
88
|
+
|
|
89
|
+
queueA.enqueue('A1');
|
|
90
|
+
queueA.enqueue('A2');
|
|
91
|
+
queueB.enqueue('B1');
|
|
92
|
+
|
|
93
|
+
// Simulate switching to session_b — visible queue is session_b's
|
|
94
|
+
let activeSessionId = 'session_b';
|
|
95
|
+
let visibleQueue = [...getOrCreateQueue(activeSessionId).getQueue()];
|
|
96
|
+
assert.equal(visibleQueue.length, 1);
|
|
97
|
+
assert.equal(visibleQueue[0].text, 'B1');
|
|
98
|
+
|
|
99
|
+
// Switch back to session_a
|
|
100
|
+
activeSessionId = 'session_a';
|
|
101
|
+
visibleQueue = [...getOrCreateQueue(activeSessionId).getQueue()];
|
|
102
|
+
assert.equal(visibleQueue.length, 2);
|
|
103
|
+
assert.equal(visibleQueue[0].text, 'A1');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('draining a specific session while viewing another returns correct messages', () => {
|
|
107
|
+
const queueA = getOrCreateQueue('session_a');
|
|
108
|
+
const queueB = getOrCreateQueue('session_b');
|
|
109
|
+
|
|
110
|
+
queueA.enqueue('A1');
|
|
111
|
+
queueA.enqueue('A2');
|
|
112
|
+
queueB.enqueue('B1');
|
|
113
|
+
|
|
114
|
+
// Active session is B, but we drain A (onStreamEnd scenario)
|
|
115
|
+
const drained = queueA.drainAll();
|
|
116
|
+
|
|
117
|
+
assert.equal(drained.length, 2);
|
|
118
|
+
assert.equal(drained[0].text, 'A1');
|
|
119
|
+
assert.equal(drained[1].text, 'A2');
|
|
120
|
+
// Session B still has its message
|
|
121
|
+
assert.equal(queueB.getLength(), 1);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('creating a new session starts with empty queue', () => {
|
|
125
|
+
getOrCreateQueue('session_a').enqueue('A1');
|
|
126
|
+
|
|
127
|
+
const queueNew = getOrCreateQueue('session_new');
|
|
128
|
+
|
|
129
|
+
assert.equal(queueNew.getLength(), 0);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('merged texts from drained session are correct', () => {
|
|
133
|
+
const queueA = getOrCreateQueue('session_a');
|
|
134
|
+
|
|
135
|
+
queueA.enqueue('Fix the bug');
|
|
136
|
+
queueA.enqueue('Also update docs');
|
|
137
|
+
|
|
138
|
+
const drained = queueA.drainAll();
|
|
139
|
+
const merged = MessageQueue.mergeTexts(drained);
|
|
140
|
+
|
|
141
|
+
assert.equal(merged, 'Fix the bug\n\nAlso update docs');
|
|
142
|
+
});
|
|
143
|
+
});
|
|
@@ -13,7 +13,7 @@ priorities, and preferences**. You interact with the graph exclusively
|
|
|
13
13
|
through the tools below.
|
|
14
14
|
|
|
15
15
|
All tools live in `assistkick-product-system/packages/shared/tools/` and
|
|
16
|
-
are run with `
|
|
16
|
+
are run with `pnpm tsx`.
|
|
17
17
|
|
|
18
18
|
## Bootstrap Philosophy
|
|
19
19
|
Unlike a greenfield interview, the project already exists. The codebase is
|
|
@@ -205,33 +205,33 @@ Use the same `<project_id>` on **every** tool call in this session.
|
|
|
205
205
|
|
|
206
206
|
### start_session
|
|
207
207
|
```
|
|
208
|
-
|
|
208
|
+
pnpm tsx packages/shared/tools/start_session.ts --project-id <project_id>
|
|
209
209
|
```
|
|
210
210
|
|
|
211
211
|
### end_session
|
|
212
212
|
```
|
|
213
|
-
|
|
213
|
+
pnpm tsx packages/shared/tools/end_session.ts --project-id <project_id> --summary "..." --nodes-touched "feat_001,dec_001" --questions-resolved 3
|
|
214
214
|
```
|
|
215
215
|
|
|
216
216
|
### search_nodes
|
|
217
217
|
```
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
218
|
+
pnpm tsx packages/shared/tools/search_nodes.ts --project-id <project_id> --query "keyword"
|
|
219
|
+
pnpm tsx packages/shared/tools/search_nodes.ts --project-id <project_id> --type feature
|
|
220
|
+
pnpm tsx packages/shared/tools/search_nodes.ts --project-id <project_id> --has-open-questions
|
|
221
|
+
pnpm tsx packages/shared/tools/search_nodes.ts --project-id <project_id> --completeness-below 0.5
|
|
222
222
|
```
|
|
223
223
|
|
|
224
224
|
### get_node
|
|
225
225
|
```
|
|
226
|
-
|
|
227
|
-
|
|
226
|
+
pnpm tsx packages/shared/tools/get_node.ts <node_id> --project-id <project_id>
|
|
227
|
+
pnpm tsx packages/shared/tools/get_node.ts --name "Node Name" --project-id <project_id>
|
|
228
228
|
```
|
|
229
229
|
Returns the node content (formatted as markdown) plus a Relations section listing
|
|
230
230
|
all connected nodes with direction, relation type, name, type, and status.
|
|
231
231
|
|
|
232
232
|
### add_node
|
|
233
233
|
```
|
|
234
|
-
|
|
234
|
+
pnpm tsx packages/shared/tools/add_node.ts --project-id <project_id> --type <type> --name "Name" --description "..."
|
|
235
235
|
```
|
|
236
236
|
Valid types: feature, component, data_entity, decision, tech_choice,
|
|
237
237
|
non_functional_requirement, design_token, design_pattern, user_role,
|
|
@@ -239,23 +239,23 @@ flow, assumption, open_question
|
|
|
239
239
|
|
|
240
240
|
### update_node
|
|
241
241
|
```
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
242
|
+
pnpm tsx packages/shared/tools/update_node.ts <id> --project-id <project_id> --add-acceptance-criteria "..."
|
|
243
|
+
pnpm tsx packages/shared/tools/update_node.ts <id> --project-id <project_id> --add-open-question "..."
|
|
244
|
+
pnpm tsx packages/shared/tools/update_node.ts <id> --project-id <project_id> --add-note "Session N: ..."
|
|
245
|
+
pnpm tsx packages/shared/tools/update_node.ts <id> --project-id <project_id> --set-status <draft|partially_defined|defined>
|
|
246
|
+
pnpm tsx packages/shared/tools/update_node.ts <id> --project-id <project_id> --set-priority <low|medium|high|blocking>
|
|
247
|
+
pnpm tsx packages/shared/tools/update_node.ts <id> --project-id <project_id> --set-description "..."
|
|
248
|
+
pnpm tsx packages/shared/tools/update_node.ts <id> --project-id <project_id> --set-section "SectionName=content"
|
|
249
249
|
```
|
|
250
250
|
|
|
251
251
|
### resolve_question
|
|
252
252
|
```
|
|
253
|
-
|
|
253
|
+
pnpm tsx packages/shared/tools/resolve_question.ts <id> --project-id <project_id> --question "..." --answer "..."
|
|
254
254
|
```
|
|
255
255
|
|
|
256
256
|
### add_edge
|
|
257
257
|
```
|
|
258
|
-
|
|
258
|
+
pnpm tsx packages/shared/tools/add_edge.ts <from_id> <relation> <to_id> --project-id <project_id>
|
|
259
259
|
```
|
|
260
260
|
Valid relations: contains, depends_on, governed_by, constrained_by,
|
|
261
261
|
implemented_with, reads_writes, exposes, consumes, performed_by,
|
|
@@ -263,25 +263,25 @@ escalates_to, relates_to
|
|
|
263
263
|
|
|
264
264
|
### remove_edge
|
|
265
265
|
```
|
|
266
|
-
|
|
266
|
+
pnpm tsx packages/shared/tools/remove_edge.ts <from_id> <relation> <to_id> --project-id <project_id>
|
|
267
267
|
```
|
|
268
268
|
|
|
269
269
|
### get_gaps
|
|
270
270
|
```
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
271
|
+
pnpm tsx packages/shared/tools/get_gaps.ts --project-id <project_id>
|
|
272
|
+
pnpm tsx packages/shared/tools/get_gaps.ts --project-id <project_id> --blocking-only
|
|
273
|
+
pnpm tsx packages/shared/tools/get_gaps.ts --project-id <project_id> --type feature
|
|
274
274
|
```
|
|
275
275
|
|
|
276
276
|
### get_status
|
|
277
277
|
```
|
|
278
|
-
|
|
278
|
+
pnpm tsx packages/shared/tools/get_status.ts --project-id <project_id>
|
|
279
279
|
```
|
|
280
280
|
|
|
281
281
|
### rebuild_index
|
|
282
282
|
```
|
|
283
|
-
|
|
284
|
-
|
|
283
|
+
pnpm tsx packages/shared/tools/rebuild_index.ts --project-id <project_id>
|
|
284
|
+
pnpm tsx packages/shared/tools/rebuild_index.ts --project-id <project_id> --dry-run
|
|
285
285
|
```
|
|
286
286
|
|
|
287
287
|
## Search Strategy
|