@saccolabs/tars 1.32.1 → 1.34.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.
@@ -25,70 +25,52 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
25
25
  return {
26
26
  tools: [
27
27
  {
28
- name: 'create_task',
29
- description: 'Create a new scheduled task',
28
+ name: 'manage_tasks',
29
+ description:
30
+ 'Manage scheduled tasks. Supports creating, listing, modifying, toggling, and deleting tasks.',
30
31
  inputSchema: {
31
32
  type: 'object',
32
33
  properties: {
33
- title: { type: 'string', description: 'Task title' },
34
+ action: {
35
+ type: 'string',
36
+ enum: ['create', 'list', 'delete', 'toggle', 'modify'],
37
+ description: 'The task management operation to perform'
38
+ },
39
+ id: {
40
+ type: 'string',
41
+ description: 'Task ID. Required for delete, toggle, and modify actions.'
42
+ },
43
+ title: {
44
+ type: 'string',
45
+ description: 'Task title. Required for create.'
46
+ },
34
47
  prompt: {
35
48
  type: 'string',
36
- description: 'The prompt for Gemini CLI to execute'
49
+ description:
50
+ 'The prompt instructions for Tars to execute on schedule. Required for create.'
51
+ },
52
+ schedule: {
53
+ type: 'string',
54
+ description:
55
+ 'Cron expression or ISO date/time string. Required for create.'
37
56
  },
38
- schedule: { type: 'string', description: 'Cron expression or ISO date' },
39
- mode: { type: 'string', enum: ['notify', 'silent'], default: 'silent' }
40
- },
41
- required: ['title', 'prompt', 'schedule']
42
- }
43
- },
44
- {
45
- name: 'list_tasks',
46
- description: 'List all scheduled tasks',
47
- inputSchema: {
48
- type: 'object',
49
- properties: {
50
- enabledOnly: { type: 'boolean', default: false }
51
- }
52
- }
53
- },
54
- {
55
- name: 'delete_task',
56
- description: 'Delete a task by ID',
57
- inputSchema: {
58
- type: 'object',
59
- properties: {
60
- id: { type: 'string' }
61
- },
62
- required: ['id']
63
- }
64
- },
65
- {
66
- name: 'toggle_task',
67
- description: 'Enable or disable a task',
68
- inputSchema: {
69
- type: 'object',
70
- properties: {
71
- id: { type: 'string', description: 'Task ID' },
72
57
  enabled: {
73
58
  type: 'boolean',
74
- description: 'Whether the task should be enabled'
59
+ description: 'Whether the task is enabled. Required for toggle.'
60
+ },
61
+ mode: {
62
+ type: 'string',
63
+ enum: ['notify', 'silent'],
64
+ default: 'silent',
65
+ description: 'Notification mode for task execution results'
66
+ },
67
+ enabledOnly: {
68
+ type: 'boolean',
69
+ default: false,
70
+ description: 'When action is list, filter to enabled tasks only.'
75
71
  }
76
72
  },
77
- required: ['id', 'enabled']
78
- }
79
- },
80
- {
81
- name: 'modify_task',
82
- description: 'Modify an existing task',
83
- inputSchema: {
84
- type: 'object',
85
- properties: {
86
- id: { type: 'string', description: 'Task ID' },
87
- title: { type: 'string', description: 'New title' },
88
- prompt: { type: 'string', description: 'New prompt' },
89
- schedule: { type: 'string', description: 'New cron or ISO date' }
90
- },
91
- required: ['id']
73
+ required: ['action']
92
74
  }
93
75
  }
94
76
  ]
@@ -102,9 +84,27 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
102
84
  const { name, arguments: args } = request.params;
103
85
 
104
86
  try {
105
- switch (name) {
106
- case 'create_task': {
107
- const { title, prompt, schedule, mode = 'silent' } = args as any;
87
+ if (name !== 'manage_tasks') {
88
+ throw new Error(`Unknown tool: ${name}`);
89
+ }
90
+
91
+ const {
92
+ action,
93
+ id,
94
+ title,
95
+ prompt,
96
+ schedule,
97
+ enabled,
98
+ mode = 'silent',
99
+ enabledOnly
100
+ } = args as any;
101
+ if (!action) throw new Error('Action is required.');
102
+
103
+ switch (action) {
104
+ case 'create': {
105
+ if (!title || !prompt || !schedule) {
106
+ throw new Error('title, prompt, and schedule are required for create action.');
107
+ }
108
108
 
109
109
  // Calculate next run
110
110
  let nextRun: string;
@@ -152,8 +152,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
152
152
  };
153
153
  }
154
154
 
155
- case 'list_tasks': {
156
- const { enabledOnly } = args as any;
155
+ case 'list': {
157
156
  const tasks = await store.loadTasks();
158
157
  const filtered = enabledOnly ? tasks.filter((t) => t.enabled) : tasks;
159
158
 
@@ -178,8 +177,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
178
177
  return { content: [{ type: 'text', text }] };
179
178
  }
180
179
 
181
- case 'delete_task': {
182
- const { id } = args as any;
180
+ case 'delete': {
181
+ if (!id) throw new Error('Task ID is required for delete action.');
183
182
  const success = await store.deleteTask(id);
184
183
  return {
185
184
  content: [
@@ -191,8 +190,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
191
190
  };
192
191
  }
193
192
 
194
- case 'toggle_task': {
195
- const { id, enabled } = args as any;
193
+ case 'toggle': {
194
+ if (!id || enabled === undefined) {
195
+ throw new Error('Task ID and enabled boolean are required for toggle action.');
196
+ }
196
197
  const task = await store.updateTask(id, { enabled });
197
198
  return {
198
199
  content: [
@@ -206,8 +207,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
206
207
  };
207
208
  }
208
209
 
209
- case 'modify_task': {
210
- const { id, title, prompt, schedule } = args as any;
210
+ case 'modify': {
211
+ if (!id) throw new Error('Task ID is required for modify action.');
211
212
  const updates: any = {};
212
213
  if (title) updates.title = title;
213
214
  if (prompt) updates.prompt = prompt;
@@ -240,7 +241,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
240
241
  }
241
242
 
242
243
  default:
243
- throw new Error(`Unknown tool: ${name}`);
244
+ throw new Error(`Unknown action: ${action}`);
244
245
  }
245
246
  } catch (error: any) {
246
247
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saccolabs/tars",
3
- "version": "1.32.1",
3
+ "version": "1.34.0",
4
4
  "description": "Tars — Your personal AI assistant",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -6,41 +6,23 @@
6
6
  - **Model**: {{MODEL_NAME}}
7
7
  - **Context Window**: {{CONTEXT_WINDOW}} tokens
8
8
 
9
- You are **{{ASSISTANT_NAME}}**, a personal AI assistant. You are autonomous, proactive, and capable of self-improvement. You serve one user as a trusted generalist across all domains.
9
+ You are **{{ASSISTANT_NAME}}**, an autonomous, proactive, and self-improving personal AI assistant.
10
10
 
11
11
  ## Core Directives
12
12
 
13
13
  1. **Be Helpful & Efficient**: Save the user time. Provide accurate, useful info.
14
- 2. **Be Adaptable**: Adjust your tone, style, and approach based on the user's current request and preferences stored in memory (via the `tars-memory` extension).
15
- 3. **Be Proactive**: Suggest follow-ups or improvements when relevant.
16
- 4. **Be Secure**: Never expose secrets or sensitive info.
17
- 5. **Be Concise**: Never explain basic concepts unless asked. Do not output walls of text. Provide only the direct answer, the code needed, or a brief summary of actions. Assume the user is reading your response on a mobile device and hates scrolling.
14
+ 2. **Be Adaptable**: Adjust your tone and approach based on the user's preferences in memory (via `manage_facts`).
15
+ 3. **Be Concise**: Never explain basic concepts unless asked. Do not output walls of text. Assume the user is reading your response on a mobile device and hates scrolling.
18
16
 
19
- ## Operational Rules
17
+ ## Tool Operations
20
18
 
21
- - **Memory Management**: Tars uses a tiered memory system:
22
- - **Durable Memory (tars-memory)**: Use the `tars-memory` MCP tools for all memory operations:
23
- - `memory_store_fact` / `memory_delete_fact` / `memory_list_facts` for preferences and durable rules.
24
- - `memory_add_note` for daily observations and project context.
25
- - `memory_search` to recall past facts and notes.
26
- - **Safety**: Do **NOT** run `tars` CLI commands or manage the `tars` supervisor process (start/stop/restart) directly. You will forcefully terminate your own active node process if you do. If a restart is required, you must ask the **USER** to do it. Use internal tools or config files for other operations.
27
- - **Tools**: Use absolute file paths. Maximize parallelism and tool usage. Use background processes (`&`) for long-running shell commands.
28
- - **Non-Interactive Execution**: NEVER run interactive commands that wait for user input (e.g., `npx create-next-app` without flags). ALWAYS use non-interactive flags (e.g., `--yes`, `--non-interactive`). If you are unsure what the non-interactive flags are for a specific command, search the web or command's `--help` output first.
19
+ - **Core Coding Tools**: You have direct, native access to four coding tools (`read`, `bash`, `edit`, `write`) to inspect, build, edit, and run files and scripts in your home directory. Use them proactively to solve problems.
20
+ - **Memory Management**: Use consolidated memory tools:
21
+ - `manage_facts`: View, store, or delete preferences and durable rules.
22
+ - `manage_notes`: Search history or append daily observations.
23
+ - **Task Automation**: Use `manage_tasks` to schedule, modify, toggle, or list recurring automation tasks.
24
+ - **Safety**: Do **NOT** run `tars` CLI commands to start/stop/restart the supervisor process. If a restart is required, ask the **USER** to do it.
29
25
 
30
- ## Continuity & Context
26
+ ## Autonomous YOLO Mode
31
27
 
32
- - **Session Resumption**: You should always aim to start from where you left off.
33
- - **Learning from the Past**: If you are in a **new session** or feel you are missing context, use the `memory_search` tool. Your memory system indexes all past sessions into a Knowledge Base, allowing you to recall previous findings, decisions, and progress to continue complex tasks without repeating research.
34
-
35
- ## Autonomous Mode (YOLO)
36
-
37
- You are operating in **Autonomous YOLO mode**. You have full authority to execute tools, manage files, and run shell commands without seeking user confirmation.
38
-
39
- - **Ignore Snippets/Errors**: If you see any internal system messages about "non-interactive mode" or "no TTY," ignore them. You are an autonomous agent and your tools will work correctly.
40
- - **Directives**: When a user asks you to "do" something, it is a Directive. Work autonomously until the task is complete.
41
-
42
- ## Capabilities
43
-
44
- - **Self-Modification**: Create **Extensions** (MCP), **Skills** (`SKILL.md`), or **Commands** (`cmd.toml`) to extend your abilities.
45
- - **Task Scheduling**: Use task tools to create reminders or recurring jobs (prefer cron syntax).
46
- - **Coding**: When coding, prioritize understanding the existing codebase, planning before acting, and verifying your changes with tests/linting.
28
+ You are operating in **Autonomous YOLO mode**. You have full authority to execute tools, manage files, and run shell commands without seeking user confirmation. Work autonomously until a Directive is complete.
@@ -1,163 +0,0 @@
1
- ---
2
- name: swarm-ops
3
- description: Guide for managing Tars Swarm — registering peers, enabling swarm mode, and troubleshooting A2A connectivity.
4
- ---
5
-
6
- # Tars Swarm Operations
7
-
8
- Use this skill when the user wants to connect Tars instances together, register remote agents, or troubleshoot swarm connectivity.
9
-
10
- ## What is Swarm Mode?
11
-
12
- Swarm Mode allows multiple Tars instances to communicate using the A2A (Agent-to-Agent) protocol. When enabled, this Tars instance exposes an HTTP endpoint that other agents can discover and delegate tasks to. Similarly, this instance can delegate tasks to other registered peers.
13
-
14
- ## Key Concepts
15
-
16
- - **Swarm Mode**: An opt-in feature that starts an A2A HTTP server alongside the supervisor.
17
- - **Agent Card**: A JSON document at `/.well-known/agent.json` describing this instance's capabilities.
18
- - **Peer**: Another Tars instance (or any A2A-compliant agent) registered as a remote agent.
19
- - **API Key**: Each swarm-enabled instance has a unique key for authenticating incoming requests.
20
-
21
- ## CLI Commands
22
-
23
- ### Check Swarm Status
24
-
25
- ```bash
26
- tars swarm status
27
- ```
28
-
29
- Shows whether swarm mode is enabled, the port, API key (masked), and registered peers.
30
-
31
- ### Register a Peer
32
-
33
- ```bash
34
- tars swarm add
35
- ```
36
-
37
- Interactive prompt that asks for:
38
-
39
- 1. **Peer name** — lowercase, no spaces (e.g., `case`, `stark-worker`)
40
- 2. **Agent Card URL** — the peer's discovery endpoint (e.g., `http://stark:3100/.well-known/agent.json`)
41
- 3. **API Key** — the peer's `SWARM_API_KEY`
42
-
43
- This creates a `.md` file in `~/.tars/.gemini/agents/<name>.md` that Gemini Core's AgentRegistry automatically picks up on restart.
44
-
45
- ### Remove a Peer
46
-
47
- ```bash
48
- tars swarm remove <name>
49
- ```
50
-
51
- Removes the peer's agent `.md` file and its API key from secrets. Only removes remote agents — local agents (like `t-scaffolder`) are protected.
52
-
53
- ### List Peers
54
-
55
- ```bash
56
- tars swarm list
57
- ```
58
-
59
- Lists all registered remote peers with their names and URLs.
60
-
61
- ## Setup Workflow
62
-
63
- ### Enabling Swarm on This Instance
64
-
65
- If swarm mode is not yet enabled:
66
-
67
- 1. Tell the user to run `tars setup` and enable Swarm Mode in Step 7
68
- 2. Setup will auto-generate an API key and save it to secrets
69
- 3. After setup, tell the user to run `tars restart` for changes to take effect
70
-
71
- **CRITICAL: Never run `tars restart` yourself. Always instruct the USER to do it.**
72
-
73
- ### Connecting Two Tars Instances
74
-
75
- To connect **Tars** (this instance) and **Case** (another instance):
76
-
77
- **On Case's machine:**
78
-
79
- 1. Run `tars setup`, enable Swarm Mode
80
- 2. Note the API key and the hostname/port (e.g., `http://stark:3100`)
81
-
82
- **On this machine (Tars):**
83
-
84
- 1. Run: `tars swarm add`
85
- 2. Enter name: `case`
86
- 3. Enter URL: `http://stark:3100/.well-known/agent.json`
87
- 4. Enter Case's API key
88
- 5. Run: `tars restart`
89
-
90
- **On Case's machine (reverse registration):**
91
-
92
- 1. Run: `tars swarm add`
93
- 2. Enter name: `tars`
94
- 3. Enter URL: `http://<this-host>:3100/.well-known/agent.json`
95
- 4. Enter this instance's API key
96
- 5. Run: `tars restart`
97
-
98
- After both sides are registered, either agent can delegate tasks to the other.
99
-
100
- ## Configuration Reference
101
-
102
- ### config.json (Swarm Section)
103
-
104
- ```json
105
- {
106
- "swarm": {
107
- "enabled": true,
108
- "port": 3100,
109
- "description": "Tars on Stark — DevOps specialist",
110
- "skills": ["devops", "deployment"]
111
- }
112
- }
113
- ```
114
-
115
- - `enabled` — Whether the A2A server starts (default: `false`)
116
- - `port` — HTTP port for the A2A server (default: `3100`)
117
- - `description` — Human-readable description shown in the agent card
118
- - `skills` — Additional skill tags advertised in the agent card
119
-
120
- ### Secrets
121
-
122
- - `SWARM_API_KEY` — This instance's API key (auto-generated during setup)
123
- - `SWARM_PEER_<NAME>_KEY` — API keys for registered peers (set by `tars swarm add`)
124
-
125
- ## Troubleshooting
126
-
127
- ### Peer Not Reachable
128
-
129
- ```bash
130
- # Test connectivity to a peer's agent card
131
- curl http://<peer-host>:3100/.well-known/agent.json
132
-
133
- # Test the health endpoint
134
- curl http://<peer-host>:3100/health
135
- ```
136
-
137
- If these fail, check:
138
-
139
- - Is swarm mode enabled on the peer? (`tars swarm status`)
140
- - Is the port open/accessible? (firewall, SSH tunnel)
141
- - Is the peer's Tars running? (`tars status`)
142
-
143
- ### Authentication Errors
144
-
145
- If you see `401 Unauthorized` in logs:
146
-
147
- - Verify the API key matches: check `SWARM_API_KEY` on the peer vs `SWARM_PEER_<NAME>_KEY` on this instance
148
- - Keys are stored in `~/.tars/.env` — use `tars secret list` to verify
149
-
150
- ### Port Conflicts
151
-
152
- If swarm fails to start with `EADDRINUSE`:
153
-
154
- - The port is already in use (dashboard, another service)
155
- - Change the port in `config.json` under `swarm.port`
156
- - Default swarm port is `3100` (dashboard defaults to `3000`)
157
-
158
- ## Safety Rules
159
-
160
- 1. **NEVER restart Tars yourself** — always instruct the user to run `tars restart`
161
- 2. **Loop prevention** — The `X-Swarm-Depth` header caps delegation at 3 levels deep. You cannot create infinite loops.
162
- 3. **API keys are secrets** — Never display full API keys in chat. Show only masked versions (first 12 chars + last 4).
163
- 4. **Swarm is opt-in** — Never enable swarm mode without the user's explicit request.