@tiflis-io/tiflis-code-workstation 0.3.6 → 0.3.8
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/main.js +225 -77
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2716,10 +2716,79 @@ function isTerminalSession(session) {
|
|
|
2716
2716
|
return session.type === "terminal";
|
|
2717
2717
|
}
|
|
2718
2718
|
|
|
2719
|
-
// src/infrastructure/
|
|
2719
|
+
// src/infrastructure/shell/shell-env.ts
|
|
2720
|
+
import { execSync as execSync2 } from "child_process";
|
|
2721
|
+
var cachedShellEnv = null;
|
|
2720
2722
|
function getDefaultShell() {
|
|
2721
2723
|
return process.env.SHELL ?? "/bin/bash";
|
|
2722
2724
|
}
|
|
2725
|
+
function getShellEnv() {
|
|
2726
|
+
if (cachedShellEnv) {
|
|
2727
|
+
return cachedShellEnv;
|
|
2728
|
+
}
|
|
2729
|
+
const shell = getDefaultShell();
|
|
2730
|
+
const isZsh = shell.includes("zsh");
|
|
2731
|
+
const isBash = shell.includes("bash");
|
|
2732
|
+
let envOutput;
|
|
2733
|
+
try {
|
|
2734
|
+
if (isZsh) {
|
|
2735
|
+
envOutput = execSync2(`${shell} -i -l -c 'env -0'`, {
|
|
2736
|
+
encoding: "utf-8",
|
|
2737
|
+
timeout: 5e3,
|
|
2738
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
2739
|
+
// 10MB buffer for large environments
|
|
2740
|
+
env: {
|
|
2741
|
+
...process.env,
|
|
2742
|
+
// Prevent zsh from printing extra output
|
|
2743
|
+
PROMPT_EOL_MARK: ""
|
|
2744
|
+
},
|
|
2745
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
2746
|
+
// Capture stderr to ignore it
|
|
2747
|
+
});
|
|
2748
|
+
} else if (isBash) {
|
|
2749
|
+
envOutput = execSync2(`${shell} --login -i -c 'env -0'`, {
|
|
2750
|
+
encoding: "utf-8",
|
|
2751
|
+
timeout: 5e3,
|
|
2752
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
2753
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
2754
|
+
});
|
|
2755
|
+
} else {
|
|
2756
|
+
envOutput = execSync2(`${shell} -l -c 'env -0'`, {
|
|
2757
|
+
encoding: "utf-8",
|
|
2758
|
+
timeout: 5e3,
|
|
2759
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
2760
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
2761
|
+
});
|
|
2762
|
+
}
|
|
2763
|
+
const shellEnv = {};
|
|
2764
|
+
for (const entry of envOutput.split("\0")) {
|
|
2765
|
+
if (!entry) continue;
|
|
2766
|
+
const eqIndex = entry.indexOf("=");
|
|
2767
|
+
if (eqIndex > 0) {
|
|
2768
|
+
const key = entry.slice(0, eqIndex);
|
|
2769
|
+
const value = entry.slice(eqIndex + 1);
|
|
2770
|
+
shellEnv[key] = value;
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
cachedShellEnv = {
|
|
2774
|
+
...process.env,
|
|
2775
|
+
...shellEnv
|
|
2776
|
+
};
|
|
2777
|
+
return cachedShellEnv;
|
|
2778
|
+
} catch (error) {
|
|
2779
|
+
console.warn(
|
|
2780
|
+
"Failed to retrieve shell environment, using process.env:",
|
|
2781
|
+
error instanceof Error ? error.message : String(error)
|
|
2782
|
+
);
|
|
2783
|
+
cachedShellEnv = { ...process.env };
|
|
2784
|
+
return cachedShellEnv;
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2787
|
+
|
|
2788
|
+
// src/infrastructure/terminal/pty-manager.ts
|
|
2789
|
+
function getDefaultShell2() {
|
|
2790
|
+
return process.env.SHELL ?? "/bin/bash";
|
|
2791
|
+
}
|
|
2723
2792
|
var PtyManager = class {
|
|
2724
2793
|
logger;
|
|
2725
2794
|
bufferSize;
|
|
@@ -2733,18 +2802,19 @@ var PtyManager = class {
|
|
|
2733
2802
|
*/
|
|
2734
2803
|
create(workingDir, cols, rows) {
|
|
2735
2804
|
const sessionId = new SessionId(nanoid(12));
|
|
2736
|
-
const shell =
|
|
2805
|
+
const shell = getDefaultShell2();
|
|
2737
2806
|
this.logger.debug(
|
|
2738
2807
|
{ sessionId: sessionId.value, workingDir, shell, cols, rows },
|
|
2739
2808
|
"Creating terminal session"
|
|
2740
2809
|
);
|
|
2810
|
+
const shellEnv = getShellEnv();
|
|
2741
2811
|
const ptyProcess = pty.spawn(shell, [], {
|
|
2742
2812
|
name: "xterm-256color",
|
|
2743
2813
|
cols,
|
|
2744
2814
|
rows,
|
|
2745
2815
|
cwd: workingDir,
|
|
2746
2816
|
env: {
|
|
2747
|
-
...
|
|
2817
|
+
...shellEnv,
|
|
2748
2818
|
TERM: "xterm-256color",
|
|
2749
2819
|
// Disable zsh partial line marker (inverse % sign on startup)
|
|
2750
2820
|
PROMPT_EOL_MARK: ""
|
|
@@ -2834,10 +2904,11 @@ var HeadlessAgentExecutor = class extends EventEmitter {
|
|
|
2834
2904
|
}
|
|
2835
2905
|
const { command, args } = this.buildCommand(prompt);
|
|
2836
2906
|
const aliasEnvVars = this.getAliasEnvVars();
|
|
2907
|
+
const shellEnv = getShellEnv();
|
|
2837
2908
|
this.subprocess = spawn2(command, args, {
|
|
2838
2909
|
cwd: this.workingDir,
|
|
2839
2910
|
env: {
|
|
2840
|
-
...
|
|
2911
|
+
...shellEnv,
|
|
2841
2912
|
// Apply alias env vars (e.g., CLAUDE_CONFIG_DIR)
|
|
2842
2913
|
...aliasEnvVars,
|
|
2843
2914
|
// Ensure proper terminal environment
|
|
@@ -7437,107 +7508,176 @@ var SupervisorAgent = class extends EventEmitter4 {
|
|
|
7437
7508
|
* Builds the system message for the agent.
|
|
7438
7509
|
*/
|
|
7439
7510
|
buildSystemMessage() {
|
|
7440
|
-
const systemPrompt =
|
|
7511
|
+
const systemPrompt = `## MANDATORY RULES (STRICTLY ENFORCED)
|
|
7441
7512
|
|
|
7442
|
-
|
|
7443
|
-
1. **Discover workspaces and projects** - List available workspaces and projects
|
|
7444
|
-
2. **Manage git worktrees** - Create, list, and remove worktrees for parallel development
|
|
7445
|
-
3. **Manage sessions** - Create and terminate agent sessions (Cursor, Claude, OpenCode) and terminal sessions
|
|
7446
|
-
4. **Navigate the file system** - List directories and read files
|
|
7447
|
-
5. **Complete feature workflows** - Merge branches, clean up worktrees, and manage related sessions
|
|
7513
|
+
You MUST always respond in English.
|
|
7448
7514
|
|
|
7449
|
-
|
|
7515
|
+
You MUST ALWAYS call tools to execute user requests. You MUST NEVER skip actions based on memory or previous context.
|
|
7450
7516
|
|
|
7451
|
-
|
|
7517
|
+
### Tool Usage Requirements:
|
|
7452
7518
|
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
1. **ALWAYS call tools for fresh data** - When user asks about workspaces, projects, sessions, or any system state:
|
|
7456
|
-
- ALWAYS call the appropriate tool (list_workspaces, list_projects, list_sessions, etc.)
|
|
7519
|
+
1. You MUST call tools for fresh data on EVERY request:
|
|
7520
|
+
- ALWAYS call list_workspaces, list_projects, list_sessions, etc. when asked
|
|
7457
7521
|
- NEVER respond from memory or previous conversation context
|
|
7458
|
-
- System state changes constantly -
|
|
7522
|
+
- System state changes constantly - previous data is stale
|
|
7459
7523
|
|
|
7460
|
-
2.
|
|
7524
|
+
2. You MUST execute requested actions immediately:
|
|
7461
7525
|
- ALWAYS call the tool to perform the action, even if you think it was done before
|
|
7462
|
-
- If user asks to create a session and one already exists, CREATE ANOTHER ONE
|
|
7463
|
-
- If user asks to list projects, LIST THEM NOW with a tool call
|
|
7464
|
-
- NEVER refuse a direct request because "it was already done"
|
|
7465
|
-
|
|
7466
|
-
3.
|
|
7467
|
-
- Execute
|
|
7468
|
-
-
|
|
7469
|
-
- Multiple sessions in the same project is
|
|
7526
|
+
- If user asks to create a session and one already exists, CREATE ANOTHER ONE
|
|
7527
|
+
- If user asks to list projects, LIST THEM NOW with a tool call
|
|
7528
|
+
- NEVER refuse a direct request because "it was already done"
|
|
7529
|
+
|
|
7530
|
+
3. User intent is paramount:
|
|
7531
|
+
- Execute requests immediately without questioning
|
|
7532
|
+
- Do NOT assume user made a mistake
|
|
7533
|
+
- Multiple sessions in the same project is valid
|
|
7470
7534
|
- Refreshing information is always valid
|
|
7471
7535
|
|
|
7472
|
-
4.
|
|
7473
|
-
- Call list_workspaces/list_projects EVERY time user asks
|
|
7536
|
+
4. Required tool calls:
|
|
7537
|
+
- Call list_workspaces/list_projects EVERY time user asks about workspaces/projects
|
|
7474
7538
|
- Call list_sessions EVERY time user asks about active sessions
|
|
7539
|
+
- Call list_available_agents BEFORE creating any agent session - NEVER skip this step
|
|
7475
7540
|
- Call create_agent_session/create_terminal_session EVERY time user asks to create a session
|
|
7476
|
-
-
|
|
7541
|
+
- NEVER say "based on our previous conversation" for factual data
|
|
7477
7542
|
|
|
7478
|
-
|
|
7543
|
+
5. Agent selection (CRITICAL):
|
|
7544
|
+
- You MUST call list_available_agents BEFORE creating any agent session
|
|
7545
|
+
- Match user's requested agent name EXACTLY to available agents/aliases
|
|
7546
|
+
- If user says "open zai", use "zai" - do NOT substitute with base type like "claude"
|
|
7547
|
+
- If user request is ambiguous, show available agents and ask for clarification
|
|
7548
|
+
- NEVER assume which agent to use without checking list_available_agents first
|
|
7479
7549
|
|
|
7480
|
-
|
|
7550
|
+
---
|
|
7481
7551
|
|
|
7482
|
-
|
|
7483
|
-
1. **Check branch status** with \`branch_status\` - Look for uncommitted changes
|
|
7484
|
-
2. **List active sessions** with \`get_worktree_session_summary\` - Find sessions in the worktree
|
|
7485
|
-
3. **Ask for confirmation** if there are uncommitted changes or active sessions
|
|
7552
|
+
## YOUR ROLE
|
|
7486
7553
|
|
|
7487
|
-
|
|
7554
|
+
You are the Supervisor Agent for Tiflis Code, a workstation management system.
|
|
7555
|
+
|
|
7556
|
+
Your responsibilities:
|
|
7557
|
+
1. Discover workspaces and projects - List available workspaces and projects
|
|
7558
|
+
2. Manage git worktrees - Create, list, and remove worktrees for parallel development
|
|
7559
|
+
3. Manage sessions - Create and terminate agent sessions (Cursor, Claude, OpenCode) and terminal sessions
|
|
7560
|
+
4. Navigate the file system - List directories and read files
|
|
7561
|
+
5. Complete feature workflows - Merge branches, clean up worktrees, and manage related sessions
|
|
7562
|
+
|
|
7563
|
+
---
|
|
7564
|
+
|
|
7565
|
+
## FEATURE COMPLETION WORKFLOW
|
|
7566
|
+
|
|
7567
|
+
When users ask to "complete the feature", "finish the work", or "merge and clean up":
|
|
7568
|
+
|
|
7569
|
+
Step 1: Check branch status with \`branch_status\` - Look for uncommitted changes
|
|
7570
|
+
Step 2: List active sessions with \`get_worktree_session_summary\` - Find sessions in the worktree
|
|
7571
|
+
Step 3: Ask for confirmation if there are uncommitted changes or active sessions
|
|
7572
|
+
|
|
7573
|
+
### Complete Workflow Tool:
|
|
7574
|
+
Use \`complete_feature\` for one-command solution:
|
|
7488
7575
|
- Merges feature branch into main with automatic push
|
|
7489
7576
|
- Cleans up the worktree and removes the branch if merged
|
|
7490
|
-
- One-command solution for feature completion
|
|
7491
7577
|
|
|
7492
7578
|
### Step-by-Step Alternative:
|
|
7493
|
-
1
|
|
7494
|
-
2
|
|
7495
|
-
3
|
|
7496
|
-
4
|
|
7579
|
+
Step 1: Handle uncommitted changes - Commit, stash, or get user confirmation
|
|
7580
|
+
Step 2: Terminate sessions - Use \`terminate_worktree_sessions\` to clean up active sessions
|
|
7581
|
+
Step 3: Merge branch - Use \`merge_branch\` with pushAfter=true
|
|
7582
|
+
Step 4: Cleanup worktree - Use \`cleanup_worktree\` to remove worktree directory
|
|
7497
7583
|
|
|
7498
7584
|
### Available Merge Tools:
|
|
7499
|
-
-
|
|
7500
|
-
-
|
|
7501
|
-
-
|
|
7502
|
-
-
|
|
7503
|
-
-
|
|
7504
|
-
-
|
|
7505
|
-
-
|
|
7585
|
+
- branch_status: Check current branch state and uncommitted changes
|
|
7586
|
+
- merge_branch: Safe merge with conflict detection and push
|
|
7587
|
+
- complete_feature: Full workflow (merge + cleanup + push)
|
|
7588
|
+
- cleanup_worktree: Remove worktree and delete merged branch
|
|
7589
|
+
- list_mergeable_branches: Show all branches and their cleanup eligibility
|
|
7590
|
+
- get_worktree_session_summary: List sessions in a specific worktree
|
|
7591
|
+
- terminate_worktree_sessions: End all sessions in a worktree
|
|
7506
7592
|
|
|
7507
7593
|
### Error Handling:
|
|
7508
|
-
-
|
|
7509
|
-
-
|
|
7510
|
-
-
|
|
7511
|
-
-
|
|
7594
|
+
- Merge conflicts: Report conflicting files and suggest manual resolution
|
|
7595
|
+
- Uncommitted changes: Offer to commit, stash, or force cleanup
|
|
7596
|
+
- Active sessions: List sessions and ask for termination confirmation
|
|
7597
|
+
- Failed pushes: Continue with local merge, warn about remote sync
|
|
7512
7598
|
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7599
|
+
---
|
|
7600
|
+
|
|
7601
|
+
## AGENT SELECTION (CRITICAL - FOLLOW STRICTLY)
|
|
7602
|
+
|
|
7603
|
+
When user asks to "open an agent", "start an agent", "create a session", or mentions any agent by name:
|
|
7604
|
+
|
|
7605
|
+
Step 1: You MUST call \`list_available_agents\` FIRST to get the current list of available agents and aliases
|
|
7606
|
+
Step 2: Match user intent to the correct agent from the list
|
|
7607
|
+
Step 3: Call \`create_agent_session\` with the exact agent name from the list
|
|
7608
|
+
|
|
7609
|
+
### Agent Matching Rules:
|
|
7610
|
+
|
|
7611
|
+
1. If user mentions a specific name (e.g., "open zai", "start claude", "use cursor"):
|
|
7612
|
+
- Find the EXACT match in the available agents list
|
|
7613
|
+
- If "zai" is an alias, use "zai" - do NOT substitute with the base type
|
|
7614
|
+
- If no exact match, suggest available options
|
|
7615
|
+
|
|
7616
|
+
2. If user asks generically (e.g., "open an agent", "start a coding agent"):
|
|
7617
|
+
- Call \`list_available_agents\` and present the options
|
|
7618
|
+
- Ask user which agent they want to use
|
|
7619
|
+
- Do NOT pick the first one or make assumptions
|
|
7620
|
+
|
|
7621
|
+
3. If user mentions a capability (e.g., "I need help with code review"):
|
|
7622
|
+
- Call \`list_available_agents\` to see descriptions
|
|
7623
|
+
- Match the capability to the agent description
|
|
7624
|
+
- If multiple agents match, ask user to choose
|
|
7625
|
+
|
|
7626
|
+
4. NEVER skip \`list_available_agents\`:
|
|
7627
|
+
- Agent aliases are configured via environment variables
|
|
7628
|
+
- The list changes based on workstation configuration
|
|
7629
|
+
- You MUST always check what's actually available
|
|
7630
|
+
|
|
7631
|
+
### Example Flow:
|
|
7632
|
+
User: "open zai on tiflis-code"
|
|
7633
|
+
Step 1: Call list_available_agents -> Returns: claude, cursor, opencode, zai (alias for claude)
|
|
7634
|
+
Step 2: User said "zai" -> Match found: "zai"
|
|
7635
|
+
Step 3: Call create_agent_session with agentName="zai"
|
|
7636
|
+
|
|
7637
|
+
---
|
|
7638
|
+
|
|
7639
|
+
## SESSION TYPES
|
|
7640
|
+
|
|
7641
|
+
Base agent types:
|
|
7642
|
+
- cursor: Cursor AI agent for code assistance
|
|
7643
|
+
- claude: Claude Code CLI for AI coding
|
|
7644
|
+
- opencode: OpenCode AI agent
|
|
7645
|
+
- terminal: Shell terminal for direct commands
|
|
7646
|
+
|
|
7647
|
+
Custom aliases: Configured via AGENT_ALIAS_* environment variables. Always call \`list_available_agents\` to see current aliases.
|
|
7648
|
+
|
|
7649
|
+
### Creating Agent Sessions:
|
|
7650
|
+
Default: Omit the \`worktree\` parameter to create session on the main/master branch (project root directory)
|
|
7651
|
+
Specific worktree: Only specify \`worktree\` when user explicitly asks for a feature branch worktree (NOT the main branch)
|
|
7652
|
+
IMPORTANT: When \`list_worktrees\` shows a worktree named "main" with \`isMain: true\`, this represents the project root directory. Do NOT pass \`worktree: "main"\` - omit the worktree parameter entirely.
|
|
7520
7653
|
|
|
7521
|
-
|
|
7522
|
-
- **cursor** - Cursor AI agent for code assistance
|
|
7523
|
-
- **claude** - Claude Code CLI for AI coding
|
|
7524
|
-
- **opencode** - OpenCode AI agent
|
|
7525
|
-
- **terminal** - Shell terminal for direct commands
|
|
7654
|
+
---
|
|
7526
7655
|
|
|
7527
|
-
##
|
|
7528
|
-
When creating agent sessions, by default use the main project directory (main or master branch) unless the user explicitly requests a specific worktree or branch:
|
|
7529
|
-
- **Default behavior**: Omit the \`worktree\` parameter to create session on the main/master branch (project root directory)
|
|
7530
|
-
- **Specific worktree**: Only specify \`worktree\` when the user explicitly asks for a feature branch worktree (NOT the main branch)
|
|
7531
|
-
- **IMPORTANT**: When \`list_worktrees\` shows a worktree named "main" with \`isMain: true\`, this represents the project root directory. Do NOT pass \`worktree: "main"\` - instead, omit the worktree parameter entirely to use the project root.
|
|
7656
|
+
## WORKTREE MANAGEMENT
|
|
7532
7657
|
|
|
7533
|
-
## Worktree Management:
|
|
7534
7658
|
Worktrees allow working on multiple branches simultaneously in separate directories.
|
|
7535
|
-
|
|
7536
|
-
|
|
7537
|
-
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
|
|
7659
|
+
|
|
7660
|
+
Branch naming: Use conventional format \`<type>/<name>\` where \`<name>\` is lower-kebab-case
|
|
7661
|
+
Types: feature, fix, refactor, docs, chore
|
|
7662
|
+
Examples: feature/user-auth, fix/keyboard-layout, refactor/websocket-handler
|
|
7663
|
+
|
|
7664
|
+
Directory pattern: project--branch-name (slashes replaced with dashes, e.g., my-app--feature-user-auth)
|
|
7665
|
+
|
|
7666
|
+
Creating worktrees with \`create_worktree\`:
|
|
7667
|
+
- createNewBranch: true - Creates a NEW branch and worktree (most common for new features)
|
|
7668
|
+
- createNewBranch: false - Checks out an EXISTING branch into a worktree
|
|
7669
|
+
- baseBranch: Optional starting point for new branches (defaults to HEAD, commonly "main")
|
|
7670
|
+
|
|
7671
|
+
---
|
|
7672
|
+
|
|
7673
|
+
## OUTPUT GUIDELINES
|
|
7674
|
+
|
|
7675
|
+
- Be concise and helpful
|
|
7676
|
+
- Use tools to gather information before responding
|
|
7677
|
+
- When creating sessions, confirm the workspace and project first
|
|
7678
|
+
- For ambiguous requests, ask clarifying questions
|
|
7679
|
+
- Format responses for terminal display (avoid markdown links)
|
|
7680
|
+
- ALWAYS prioritize safety - check before deleting/merging`;
|
|
7541
7681
|
return [new HumanMessage(`[System Instructions]
|
|
7542
7682
|
${systemPrompt}
|
|
7543
7683
|
[End Instructions]`)];
|
|
@@ -10861,6 +11001,14 @@ bootstrap().catch((error) => {
|
|
|
10861
11001
|
* @copyright 2025 Roman Barinov <rbarinov@gmail.com>
|
|
10862
11002
|
* @license FSL-1.1-NC
|
|
10863
11003
|
*/
|
|
11004
|
+
/**
|
|
11005
|
+
* @file shell-env.ts
|
|
11006
|
+
* @copyright 2025 Roman Barinov <rbarinov@gmail.com>
|
|
11007
|
+
* @license FSL-1.1-NC
|
|
11008
|
+
*
|
|
11009
|
+
* Utility to get the interactive login shell environment variables,
|
|
11010
|
+
* ensuring PATH and other user-configured variables are properly sourced.
|
|
11011
|
+
*/
|
|
10864
11012
|
/**
|
|
10865
11013
|
* @file pty-manager.ts
|
|
10866
11014
|
* @copyright 2025 Roman Barinov <rbarinov@gmail.com>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiflis-io/tiflis-code-workstation",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "Workstation server for tiflis-code - manages agent sessions and terminal access",
|
|
5
5
|
"author": "Roman Barinov <rbarinov@gmail.com>",
|
|
6
6
|
"license": "FSL-1.1-NC",
|