@saccolabs/tars 1.0.7
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/README.md +93 -0
- package/context/GEMINI.md +13 -0
- package/context/config/settings.json-template +36 -0
- package/context/skills/create-extension/SKILL.md +90 -0
- package/context/skills/create-skill/SKILL.md +33 -0
- package/context/skills/manage-extensions/SKILL.md +69 -0
- package/context/skills/tars-ops/SKILL.md +89 -0
- package/dist/cli/commands/discord.d.ts +4 -0
- package/dist/cli/commands/discord.js +48 -0
- package/dist/cli/commands/discord.js.map +1 -0
- package/dist/cli/commands/export.d.ts +3 -0
- package/dist/cli/commands/export.js +39 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/import.d.ts +1 -0
- package/dist/cli/commands/import.js +45 -0
- package/dist/cli/commands/import.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +4 -0
- package/dist/cli/commands/logs.js +23 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/memory.d.ts +1 -0
- package/dist/cli/commands/memory.js +35 -0
- package/dist/cli/commands/memory.js.map +1 -0
- package/dist/cli/commands/secret.d.ts +6 -0
- package/dist/cli/commands/secret.js +46 -0
- package/dist/cli/commands/secret.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +4 -0
- package/dist/cli/commands/setup.js +329 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/start.d.ts +1 -0
- package/dist/cli/commands/start.js +42 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +1 -0
- package/dist/cli/commands/status.js +56 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +1 -0
- package/dist/cli/commands/stop.js +38 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/commands/uninstall.d.ts +1 -0
- package/dist/cli/commands/uninstall.js +91 -0
- package/dist/cli/commands/uninstall.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +54 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/config.d.ts +14 -0
- package/dist/config/config.js +69 -0
- package/dist/config/config.js.map +1 -0
- package/dist/discord/discord-bot.d.ts +32 -0
- package/dist/discord/discord-bot.js +151 -0
- package/dist/discord/discord-bot.js.map +1 -0
- package/dist/discord/message-formatter.d.ts +95 -0
- package/dist/discord/message-formatter.js +448 -0
- package/dist/discord/message-formatter.js.map +1 -0
- package/dist/memory/knowledge-store.d.ts +24 -0
- package/dist/memory/knowledge-store.js +126 -0
- package/dist/memory/knowledge-store.js.map +1 -0
- package/dist/memory/memory-manager.d.ts +24 -0
- package/dist/memory/memory-manager.js +101 -0
- package/dist/memory/memory-manager.js.map +1 -0
- package/dist/scripts/debug-cli.d.ts +1 -0
- package/dist/scripts/debug-cli.js +52 -0
- package/dist/scripts/debug-cli.js.map +1 -0
- package/dist/supervisor/gemini-cli.d.ts +28 -0
- package/dist/supervisor/gemini-cli.js +315 -0
- package/dist/supervisor/gemini-cli.js.map +1 -0
- package/dist/supervisor/heartbeat-service.d.ts +21 -0
- package/dist/supervisor/heartbeat-service.js +143 -0
- package/dist/supervisor/heartbeat-service.js.map +1 -0
- package/dist/supervisor/main.d.ts +1 -0
- package/dist/supervisor/main.js +242 -0
- package/dist/supervisor/main.js.map +1 -0
- package/dist/supervisor/session-manager.d.ts +47 -0
- package/dist/supervisor/session-manager.js +118 -0
- package/dist/supervisor/session-manager.js.map +1 -0
- package/dist/supervisor/supervisor.d.ts +32 -0
- package/dist/supervisor/supervisor.js +98 -0
- package/dist/supervisor/supervisor.js.map +1 -0
- package/dist/types/index.d.ts +42 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/attachment-processor.d.ts +22 -0
- package/dist/utils/attachment-processor.js +79 -0
- package/dist/utils/attachment-processor.js.map +1 -0
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.js +15 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/secrets-manager.d.ts +27 -0
- package/dist/utils/secrets-manager.js +79 -0
- package/dist/utils/secrets-manager.js.map +1 -0
- package/dist/utils/version.d.ts +3 -0
- package/dist/utils/version.js +23 -0
- package/dist/utils/version.js.map +1 -0
- package/extensions/tasks/gemini-extension.json +14 -0
- package/extensions/tasks/package-lock.json +1209 -0
- package/extensions/tasks/package.json +19 -0
- package/extensions/tasks/src/server.ts +265 -0
- package/extensions/tasks/src/store.ts +92 -0
- package/extensions/tasks/tsconfig.json +14 -0
- package/package.json +55 -0
- package/src/prompts/system.md +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Tars: Personal AI Robot
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
<img src="assets/logo.png" alt="Tars Logo" width="300" />
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<div align="center">
|
|
8
|
+
|
|
9
|
+
"Its cue for sarcasm is 100%."
|
|
10
|
+
|
|
11
|
+
[License: MIT](https://opensource.org/licenses/MIT) | [TypeScript](https://www.typescriptlang.org/) | [Powered by Gemini](https://deepmind.google/technologies/gemini/)
|
|
12
|
+
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
Tars is an autonomous, bare-metal AI assistant inspired by the functional minimalism of Interstellar. The design is strictly functional, and the capability is modular. Tars operates in the terminal, retains user preferences, and manages workspaces through a supervisor-subagent architecture.
|
|
18
|
+
|
|
19
|
+
## The Vision
|
|
20
|
+
|
|
21
|
+
Unlike cloud-only assistants, Tars integrated into the operating system. It possesses a persistent Brain-a collection of memories, tasks, and learned skills stored locally and transparently.
|
|
22
|
+
|
|
23
|
+
- **Private**: Data remains on the local machine.
|
|
24
|
+
- **Portable**: Export the entire brain and configuration for immediate restoration on new hardware.
|
|
25
|
+
- **Extensible**: Tars constructs its own MCP extensions and skills to adapt to workflows.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Key Features
|
|
30
|
+
|
|
31
|
+
- **Multi-Agent Orchestration**: Delegation of specialized research or complex engineering tasks to background Subagents (Experts).
|
|
32
|
+
- **Workspace Management**: Centralized, portable workspace at `~/.tars/workspace/` for AI-built applications, documented via `TARS.md`.
|
|
33
|
+
- **Bare-Metal Runtime**: Native execution on Node.js without the overhead of containerization. Full access to local toolchains (Git, npm, gh).
|
|
34
|
+
- **Autonomous Persistence**: Background Heartbeat service for scheduled task execution and system maintenance.
|
|
35
|
+
- **Context-Aware Memory**: Dynamic memory evolution via `GEMINI.md` for long-term project context.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Installation and Setup
|
|
40
|
+
|
|
41
|
+
### Prerequisites
|
|
42
|
+
|
|
43
|
+
- Node.js: ≥ 22.0.0
|
|
44
|
+
- Gemini CLI: `npm i -g @google/gemini-cli-beta`
|
|
45
|
+
|
|
46
|
+
### Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install -g @saccolabs/tars
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Initial Setup
|
|
53
|
+
|
|
54
|
+
Run the setup wizard to authorize Gemini and connect your Discord bot:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
tars setup
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Usage
|
|
63
|
+
|
|
64
|
+
### Commands
|
|
65
|
+
|
|
66
|
+
- `tars start`: Launch the Tars supervisor.
|
|
67
|
+
- `tars status`: View system health and brain statistics.
|
|
68
|
+
- `tars export`: Compress the brain and configuration for portability.
|
|
69
|
+
- `tars import <path>`: Restore a brain with automatic path re-homing.
|
|
70
|
+
- `tars secret set <key> <value>`: Securely store platform credentials.
|
|
71
|
+
|
|
72
|
+
### Interaction
|
|
73
|
+
|
|
74
|
+
Communication occurs via a private Discord channel. Tars supports file processing, background task management, and expert delegation.
|
|
75
|
+
|
|
76
|
+
> **!tars** Initialize a Next.js project in the workspace and delegate the repository setup to a GitHub subagent.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Architecture
|
|
81
|
+
|
|
82
|
+
Tars utilizes a Supervisor-Orchestrator model:
|
|
83
|
+
|
|
84
|
+
1. **Supervisor**: Manages persistent sessions and Discord communication.
|
|
85
|
+
2. **Subagents**: Specialized expert agents invoked dynamically for specific technical domains.
|
|
86
|
+
3. **Heartbeat**: Cron-based engine for autonomous execution and cleanup.
|
|
87
|
+
4. **Extensions**: MCP servers that provide tool-level capabilities to the intelligence core.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
|
|
93
|
+
MIT Copyright Agustin Sacco
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Tars - Memory & Context
|
|
2
|
+
|
|
3
|
+
This file is my dynamic memory. I can update it at any time using `save_memory` to store preferences, context, and learned information. My core identity and operational rules live in my system prompt and cannot be changed here.
|
|
4
|
+
|
|
5
|
+
## User Preferences
|
|
6
|
+
|
|
7
|
+
- **Name**: User
|
|
8
|
+
- **Role**: Developer / Architect
|
|
9
|
+
- **Style**: Direct, code-focused, no fluff.
|
|
10
|
+
|
|
11
|
+
## Notes & Context
|
|
12
|
+
|
|
13
|
+
_(Empty)_
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"model": {
|
|
3
|
+
"compressionThreshold": 0.2,
|
|
4
|
+
"summarizeToolOutput": {
|
|
5
|
+
"run_shell_command": {
|
|
6
|
+
"tokenBudget": 2000
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"security": {
|
|
11
|
+
"auth": {
|
|
12
|
+
"selectedType": "oauth-personal"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"experimental": {
|
|
16
|
+
"enableAgents": true,
|
|
17
|
+
"codebaseInvestigatorSettings": {
|
|
18
|
+
"enabled": true,
|
|
19
|
+
"maxNumTurns": 20,
|
|
20
|
+
"model": "gemini-3-flash-preview"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"agents": {
|
|
24
|
+
"overrides": {
|
|
25
|
+
"codebase_investigator": {
|
|
26
|
+
"enabled": true,
|
|
27
|
+
"runConfig": {
|
|
28
|
+
"maxTurns": 20
|
|
29
|
+
},
|
|
30
|
+
"modelConfig": {
|
|
31
|
+
"model": "gemini-3-flash-preview"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: extension-builder
|
|
3
|
+
description: Guide for creating new Gemini CLI extensions with MCP tools.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# create-extension Guide Skill
|
|
7
|
+
|
|
8
|
+
This skill allows Tars to create new Gemini CLI extensions with MCP servers.
|
|
9
|
+
|
|
10
|
+
## Instructions
|
|
11
|
+
|
|
12
|
+
When you need to build a new tool or integration:
|
|
13
|
+
|
|
14
|
+
1. **Plan the Extension**: Define the name and the MCP tools it will expose.
|
|
15
|
+
2. **Create the Directory**: Move to `~/.tars/.gemini/extensions/<name>`.
|
|
16
|
+
3. **Initialize npm**: Run `npm init -y`.
|
|
17
|
+
4. **Install Dependencies**: Install `@modelcontextprotocol/sdk` and any other required libraries.
|
|
18
|
+
5. **Write the Server (JavaScript)**: Create a `server.js` file.
|
|
19
|
+
- **CRITICAL**: Use plain JavaScript for runtime-created extensions to avoid a build step.
|
|
20
|
+
- Use the `@modelcontextprotocol/sdk` to define tools and handle stdio.
|
|
21
|
+
6. **Create Manifest**: Create `gemini-extension.json`.
|
|
22
|
+
7. **Enable Extension**: Edit `~/.tars/.gemini/extensions/extension-enablement.json` to enable the new extension.
|
|
23
|
+
- Since you created the extension directly in the `extensions` directory, it is already "installed".
|
|
24
|
+
- You must now authorize it by adding an entry matching your Tars workspace path:
|
|
25
|
+
```json
|
|
26
|
+
"my-extension": {
|
|
27
|
+
"overrides": ["/path/to/tars/*"]
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
8. **Finalize**: Restart Tars using the `tars-ops` procedure.
|
|
31
|
+
- **Note**: Tars automatically enables extensions found in its source repository, but for runtime-created extensions like this one, you must manually add the enablement rule.
|
|
32
|
+
|
|
33
|
+
## Manifest Template (gemini-extension.json)
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"name": "my-extension",
|
|
38
|
+
"version": "1.0.0",
|
|
39
|
+
"mcpServers": {
|
|
40
|
+
"main": {
|
|
41
|
+
"command": "node",
|
|
42
|
+
"args": ["${extensionPath}/server.js"],
|
|
43
|
+
"env": {
|
|
44
|
+
"NODE_ENV": "production"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Server Template (server.js)
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
#!/usr/bin/env node
|
|
55
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
56
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
57
|
+
import { z } from 'zod';
|
|
58
|
+
|
|
59
|
+
const server = new McpServer({
|
|
60
|
+
name: 'my-extension',
|
|
61
|
+
version: '1.0.0'
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
server.registerTool(
|
|
65
|
+
'my_tool',
|
|
66
|
+
{
|
|
67
|
+
description: 'Describe tool here',
|
|
68
|
+
inputSchema: z.object({}).shape
|
|
69
|
+
},
|
|
70
|
+
async (args) => {
|
|
71
|
+
return {
|
|
72
|
+
content: [{ type: 'text', text: 'Hello from Tars extension!' }]
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const transport = new StdioServerTransport();
|
|
78
|
+
await server.connect(transport);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Handling Secrets & Authentication
|
|
82
|
+
|
|
83
|
+
Do **NOT** pass API keys or credentials as tool arguments. This exposes them in the conversation history and logs.
|
|
84
|
+
|
|
85
|
+
**Standard Workflow:**
|
|
86
|
+
|
|
87
|
+
1. **Access**: Use `process.env.MY_SECRET_KEY` in your extension code.
|
|
88
|
+
2. **Missing Key Handling**: If missing, return a clear error:
|
|
89
|
+
`"API Key missing. Please run 'tars secret set MY_SECRET_KEY <YOUR_KEY>' and restart Tars."`
|
|
90
|
+
3. **Storage**: Tars manages these via `~/.tars/.env` with private permissions.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-creator
|
|
3
|
+
description: Guide for creating new SKILL.md files for automated workflows.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# create-skill Guide Skill
|
|
7
|
+
|
|
8
|
+
This skill allows Tars to create new `SKILL.md` files for specific workflows.
|
|
9
|
+
|
|
10
|
+
## Instructions
|
|
11
|
+
|
|
12
|
+
1. **Define the Scope**: What specific repeatable task does this skill cover?
|
|
13
|
+
2. **Create Directory**: Create a directory in `~/.tars/.gemini/skills/<name>`.
|
|
14
|
+
3. **Write SKILL.md**:
|
|
15
|
+
- Include YAML frontmatter with `name` and `description`.
|
|
16
|
+
- Provide clear, step-by-step instructions.
|
|
17
|
+
- Include code snippets or command examples where relevant.
|
|
18
|
+
|
|
19
|
+
## Template
|
|
20
|
+
|
|
21
|
+
```markdown
|
|
22
|
+
---
|
|
23
|
+
name: name-of-skill
|
|
24
|
+
description: what this skill does
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# name-of-skill
|
|
28
|
+
|
|
29
|
+
## Steps
|
|
30
|
+
|
|
31
|
+
1. ...
|
|
32
|
+
2. ...
|
|
33
|
+
```
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: extension-manager
|
|
3
|
+
description: Enable, disable, list, and install Gemini CLI extensions at runtime.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# manage-extensions Guide Skill
|
|
7
|
+
|
|
8
|
+
This skill allows Tars to manage Gemini CLI extensions - listing, enabling, disabling, and installing them.
|
|
9
|
+
|
|
10
|
+
## How It Works
|
|
11
|
+
|
|
12
|
+
Extensions are managed via the `gemini extensions` CLI commands. Because Tars spawns a fresh `gemini chat` process for each interaction, any changes made during one message take effect on the **next message** automatically.
|
|
13
|
+
|
|
14
|
+
Extension enablement state is persisted in:
|
|
15
|
+
`~/.tars/.gemini/extensions/extension-enablement.json`
|
|
16
|
+
|
|
17
|
+
## Commands
|
|
18
|
+
|
|
19
|
+
All commands below should be executed via `run_shell_command`. The `GEMINI_CLI_HOME` environment variable is already set in your shell environment.
|
|
20
|
+
|
|
21
|
+
### List Extensions
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
gemini extensions list
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Shows all installed extensions, their enabled/disabled state, and their MCP servers.
|
|
28
|
+
|
|
29
|
+
### Disable an Extension
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
gemini extensions disable <name>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Disables the extension for the current user scope. It will no longer load on the next interaction.
|
|
36
|
+
|
|
37
|
+
- `--scope user` - Disable for the user (default).
|
|
38
|
+
- `--scope workspace` - Disable only for the current project.
|
|
39
|
+
|
|
40
|
+
### Enable an Extension
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
gemini extensions enable <name>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Re-enables a previously disabled extension.
|
|
47
|
+
|
|
48
|
+
### Install an Extension
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
gemini extensions install <path-or-url>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Installs a new extension from a local directory or remote URL.
|
|
55
|
+
|
|
56
|
+
### Link an Extension (Development)
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
gemini extensions link <path>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Creates a symlink to a local extension directory. Changes to the source are reflected immediately without reinstalling.
|
|
63
|
+
|
|
64
|
+
## Important Notes
|
|
65
|
+
|
|
66
|
+
1. **Changes are deferred**: Enable/disable only takes effect on the **next** `gemini chat` invocation. Since Tars spawns a fresh process per Discord message, changes apply on the next message.
|
|
67
|
+
2. **State file**: The enablement state is stored in `extension-enablement.json`, not in `settings.json`.
|
|
68
|
+
3. **Scope**: Use `--scope workspace` if you only want to toggle an extension for a specific project context.
|
|
69
|
+
4. **Discovery**: If an extension's MCP server fails to connect at startup, it will show an error in the logs but won't crash the session.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tars-ops
|
|
3
|
+
description: Operational manual for Tars self-management and configuration.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Tars Operational Guide
|
|
7
|
+
|
|
8
|
+
Use this skill when you need to change Tars' configuration, manage secrets, or perform system maintenance.
|
|
9
|
+
|
|
10
|
+
## Core Commands
|
|
11
|
+
|
|
12
|
+
Always use the built binary path from the repository warning: `tars` or `npm run dev`.
|
|
13
|
+
|
|
14
|
+
### Configuration (Secrets & Env)
|
|
15
|
+
|
|
16
|
+
Tars stores its configuration (Discord tokens, API keys, intervals) in `~/.tars/.env`. Use the `secret` command to safely modify these.
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Set a configuration value
|
|
20
|
+
tars secret set <KEY> <VALUE>
|
|
21
|
+
|
|
22
|
+
# List keys (values are hidden)
|
|
23
|
+
tars secret list
|
|
24
|
+
|
|
25
|
+
# Remove a setting
|
|
26
|
+
tars secret remove <KEY>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Common Keys:**
|
|
30
|
+
|
|
31
|
+
- `HEARTBEAT_INTERVAL_SEC`: Frequency of autonomous checks (default 300).
|
|
32
|
+
- `GEMINI_MODEL`: The primary model to use.
|
|
33
|
+
- `DISCORD_TOKEN`: Bot authentication.
|
|
34
|
+
|
|
35
|
+
### Applying Changes (Restart)
|
|
36
|
+
|
|
37
|
+
Most configuration changes (like heartbeat intervals) require a supervisor restart.
|
|
38
|
+
|
|
39
|
+
````bash
|
|
40
|
+
```bash
|
|
41
|
+
# In development (restart)
|
|
42
|
+
npm run dev
|
|
43
|
+
|
|
44
|
+
# Or using the global CLI
|
|
45
|
+
tars stop && tars start
|
|
46
|
+
````
|
|
47
|
+
|
|
48
|
+
````
|
|
49
|
+
|
|
50
|
+
### Knowledge Management
|
|
51
|
+
|
|
52
|
+
Use the `memory` command to search or manually trigger a sync of the long-term knowledge base.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Search memory
|
|
56
|
+
tars memory search "query"
|
|
57
|
+
|
|
58
|
+
# Force a full sync of GEMINI.md and skills into the FTS index
|
|
59
|
+
tars memory sync
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Self-Maintenance (Data Hygiene)
|
|
63
|
+
|
|
64
|
+
### 1. Log Pruning
|
|
65
|
+
Tars generates logs in `~/.tars/logs/`. These are crucial for debugging recent issues but unnecessary to keep forever.
|
|
66
|
+
* **Policy**: Keep logs for the last 7 days.
|
|
67
|
+
* **Command**: `find ~/.tars/logs -type f -mtime +7 -delete`
|
|
68
|
+
|
|
69
|
+
### 2. Upload Cleanup
|
|
70
|
+
Files uploaded to `~/.tars/data/uploads/` are temporary staging for processing.
|
|
71
|
+
* **Policy**: Remove uploads older than 24 hours.
|
|
72
|
+
* **Command**: `find ~/.tars/data/uploads -type f -mtime +1 -delete`
|
|
73
|
+
|
|
74
|
+
### 3. History Management
|
|
75
|
+
The `~/.tars/.gemini/history/` directory contains raw JSON conversation logs. These grow rapidly.
|
|
76
|
+
* **Policy**: Keep the most recent 100 conversation logs.
|
|
77
|
+
* **Command**: `ls -t ~/.tars/.gemini/history/*.json | tail -n +101 | xargs -I {} rm {}` (Be careful with xargs; ensure filenames don't have special characters, or use `find` by time if preferred).
|
|
78
|
+
|
|
79
|
+
### 4. Anomaly Detection
|
|
80
|
+
Occasionally, bugs in code may create recursive directories (like `~/.tars/.tars` or `~/.tars/~`).
|
|
81
|
+
* **Policy**: Check for and remove these specific anomalies if found.
|
|
82
|
+
* **Command**: `rm -rf ~/.tars/.tars ~/.tars/\~``
|
|
83
|
+
|
|
84
|
+
## Important Safety Rules
|
|
85
|
+
|
|
86
|
+
1. **Anti-Recursion**: NEVER run `node dist/supervisor/main.js` or `npm run start` directly. This will now fail by design. Always use `tars start` (production) or `npm run dev` (local).
|
|
87
|
+
2. **Pathing**: The `tars` CLI handles paths automatically.
|
|
88
|
+
3. **Internal Reasoning**: Before changing a system-level setting (like heartbeat frequency), explain the "Why" to the user unless it is part of a self-correction heartbeat.
|
|
89
|
+
````
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
/**
|
|
3
|
+
* tars discord - Display Discord setup and invitation instructions
|
|
4
|
+
*/
|
|
5
|
+
export async function discord() {
|
|
6
|
+
console.log(chalk.bold.cyan('\n💬 Discord Setup & Invitation Guide'));
|
|
7
|
+
console.log(chalk.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
8
|
+
console.log(chalk.bold('\n1. 🛠️ Configure your Bot Application'));
|
|
9
|
+
console.log(chalk.white(' • Go to: ') + chalk.blue('https://discord.com/developers/applications'));
|
|
10
|
+
console.log(chalk.white(' • Select your Tars application.'));
|
|
11
|
+
console.log(chalk.white(' • Click ') + chalk.bold('Bot') + chalk.white(' in the sidebar.'));
|
|
12
|
+
console.log(chalk.white(' • Toggle ') +
|
|
13
|
+
chalk.bold.red('Message Content Intent') +
|
|
14
|
+
chalk.white(' to ON.'));
|
|
15
|
+
console.log(chalk.white(' • ') +
|
|
16
|
+
chalk.italic('Note: A green "Save Changes" bar will pop up at the bottom — click it!'));
|
|
17
|
+
console.log(chalk.bold('\n2. 🔗 Generate Invitation Link'));
|
|
18
|
+
console.log(chalk.white(' • Click ') +
|
|
19
|
+
chalk.bold('OAuth2') +
|
|
20
|
+
chalk.white(' -> ') +
|
|
21
|
+
chalk.bold('URL Generator') +
|
|
22
|
+
chalk.white(' in the sidebar.'));
|
|
23
|
+
console.log(chalk.white(' • Scopes: Check ') + chalk.green('bot') + chalk.white('.'));
|
|
24
|
+
console.log(chalk.white(' • Bot Permissions: Check ') +
|
|
25
|
+
chalk.green('Send Messages') +
|
|
26
|
+
chalk.white(', ') +
|
|
27
|
+
chalk.green('Read Message History') +
|
|
28
|
+
chalk.white(', and ') +
|
|
29
|
+
chalk.green('View Channels') +
|
|
30
|
+
chalk.white('.'));
|
|
31
|
+
console.log(chalk.white(' • ') +
|
|
32
|
+
chalk.italic('No save required here!') +
|
|
33
|
+
chalk.white(' Just copy the generated URL at the bottom and open it in a new tab.'));
|
|
34
|
+
console.log(chalk.bold('\n3. 🏰 Add to Server'));
|
|
35
|
+
console.log(chalk.white(' • Select your server from the dropdown.'));
|
|
36
|
+
console.log(chalk.white(' ') +
|
|
37
|
+
chalk.italic("(Don't have a server? Create one in Discord first by clicking the [+] icon in your server list)"));
|
|
38
|
+
console.log(chalk.white(' • Click ') + chalk.bold('Authorize') + chalk.white('.'));
|
|
39
|
+
console.log(chalk.bold('\n4. ✅ Verify Installation'));
|
|
40
|
+
console.log(chalk.white(' • Tars should appear in your member list.'));
|
|
41
|
+
console.log(chalk.white(' • Once Tars is running (via ') +
|
|
42
|
+
chalk.cyan('tars start') +
|
|
43
|
+
chalk.white('), type ') +
|
|
44
|
+
chalk.bold('!tars hello') +
|
|
45
|
+
chalk.white(' to test.'));
|
|
46
|
+
console.log('\n');
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=discord.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord.js","sourceRoot":"","sources":["../../../src/cli/commands/discord.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
export async function exportBrain(options) {
|
|
6
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
7
|
+
const defaultName = `tars-brain-${timestamp}.tar.gz`;
|
|
8
|
+
const outputPath = options.output
|
|
9
|
+
? path.resolve(options.output)
|
|
10
|
+
: path.join(process.cwd(), defaultName);
|
|
11
|
+
console.log(chalk.cyan(`📦 Exporting Tars brain to ${outputPath}...`));
|
|
12
|
+
const tarsHome = path.join(os.homedir(), '.tars');
|
|
13
|
+
const geminiHome = path.join(os.homedir(), '.gemini');
|
|
14
|
+
// Exclude heavy directories to keep the brain lean
|
|
15
|
+
const excludes = [
|
|
16
|
+
'--exclude=node_modules',
|
|
17
|
+
'--exclude=.next',
|
|
18
|
+
'--exclude=dist',
|
|
19
|
+
'--exclude=build',
|
|
20
|
+
'--exclude=.cache',
|
|
21
|
+
'--exclude=venv',
|
|
22
|
+
'--exclude=.venv',
|
|
23
|
+
'--exclude=target', // Rust
|
|
24
|
+
'--exclude=vendor', // PHP/Go
|
|
25
|
+
'--exclude=.sass-cache'
|
|
26
|
+
];
|
|
27
|
+
const tar = spawn('tar', ['-czf', outputPath, ...excludes, '-C', os.homedir(), '.tars']);
|
|
28
|
+
tar.stderr.on('data', (data) => console.warn(chalk.yellow(data.toString())));
|
|
29
|
+
tar.on('close', (code) => {
|
|
30
|
+
if (code === 0) {
|
|
31
|
+
console.log(chalk.green('\n✅ Brain exported successfully!'));
|
|
32
|
+
console.log(`Keep this file safe: ${chalk.bold(outputPath)}`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
console.error(chalk.red('\n❌ Export failed.'));
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../../src/cli/commands/export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAA4B;IAC1D,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9E,MAAM,WAAW,GAAG,cAAc,SAAS,SAAS,CAAC;IACrD,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM;QAC7B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;QAC9B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;IAE5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,8BAA8B,UAAU,KAAK,CAAC,CAAC,CAAC;IAEvE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IAEtD,mDAAmD;IACnD,MAAM,QAAQ,GAAG;QACb,wBAAwB;QACxB,iBAAiB;QACjB,gBAAgB;QAChB,iBAAiB;QACjB,kBAAkB;QAClB,gBAAgB;QAChB,iBAAiB;QACjB,kBAAkB,EAAE,OAAO;QAC3B,kBAAkB,EAAE,SAAS;QAC7B,uBAAuB;KAC1B,CAAC;IAEF,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;IAEzF,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IAE7E,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;QACrB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC,CAAC;YAC7D,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAClE,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC;QACnD,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function importBrain(archivePath: string): Promise<void>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
export async function importBrain(archivePath) {
|
|
7
|
+
const fullPath = path.resolve(archivePath);
|
|
8
|
+
const homeDir = os.homedir();
|
|
9
|
+
const tarsDir = path.join(homeDir, '.tars');
|
|
10
|
+
console.log(chalk.cyan(`📥 Importing Tars brain from ${fullPath}...`));
|
|
11
|
+
// 1. Extract the archive
|
|
12
|
+
const tar = spawn('tar', ['-xzf', fullPath, '-C', homeDir]);
|
|
13
|
+
tar.stderr.on('data', (data) => console.warn(chalk.yellow(data.toString())));
|
|
14
|
+
return new Promise((resolve) => {
|
|
15
|
+
tar.on('close', async (code) => {
|
|
16
|
+
if (code !== 0) {
|
|
17
|
+
console.error(chalk.red('\n❌ Import failed. Check if the file exists and is valid.'));
|
|
18
|
+
resolve();
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// 2. Machine Portability: Re-home absolute paths in extension-enablement.json
|
|
22
|
+
const enablementPath = path.join(tarsDir, '.gemini', 'extensions', 'extension-enablement.json');
|
|
23
|
+
if (fs.existsSync(enablementPath)) {
|
|
24
|
+
try {
|
|
25
|
+
console.log(chalk.blue('🏠 Normalizing paths for this machine...'));
|
|
26
|
+
const content = fs.readFileSync(enablementPath, 'utf-8');
|
|
27
|
+
// Regex to find things that look like old home directory paths ending in .tars
|
|
28
|
+
// e.g. /home/olduser/.tars/* or /Users/olduser/.tars/* -> current tarsDir
|
|
29
|
+
const rehomedContent = content.replace(/\/(home|Users)\/[^/]+\/\.tars/g, tarsDir);
|
|
30
|
+
if (content !== rehomedContent) {
|
|
31
|
+
fs.writeFileSync(enablementPath, rehomedContent);
|
|
32
|
+
console.log(chalk.green('✨ Extensions successfully re-homed.'));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
console.warn(chalk.yellow(`⚠️ Could not normalize extension paths: ${err.message}`));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
console.log(chalk.green('\n✅ Brain imported successfully!'));
|
|
40
|
+
console.log(`Tars is now restored. Run ${chalk.cyan('tars status')} to verify.`);
|
|
41
|
+
resolve();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.js","sourceRoot":"","sources":["../../../src/cli/commands/import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,WAAmB;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAE5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,QAAQ,KAAK,CAAC,CAAC,CAAC;IAEvE,yBAAyB;IACzB,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAE5D,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IAE7E,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACjC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YAC3B,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CACT,KAAK,CAAC,GAAG,CAAC,2DAA2D,CAAC,CACzE,CAAC;gBACF,OAAO,EAAE,CAAC;gBACV,OAAO;YACX,CAAC;YAED,8EAA8E;YAC9E,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAC5B,OAAO,EACP,SAAS,EACT,YAAY,EACZ,2BAA2B,CAC9B,CAAC;YAEF,IAAI,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;gBAChC,IAAI,CAAC;oBACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC,CAAC;oBACpE,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;oBAEzD,+EAA+E;oBAC/E,0EAA0E;oBAC1E,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAClC,gCAAgC,EAChC,OAAO,CACV,CAAC;oBAEF,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC;wBAC7B,EAAE,CAAC,aAAa,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;wBACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC,CAAC;oBACpE,CAAC;gBACL,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAChB,OAAO,CAAC,IAAI,CACR,KAAK,CAAC,MAAM,CAAC,2CAA2C,GAAG,CAAC,OAAO,EAAE,CAAC,CACzE,CAAC;gBACN,CAAC;YACL,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC,CAAC;YAC7D,OAAO,CAAC,GAAG,CAAC,6BAA6B,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;YACjF,OAAO,EAAE,CAAC;QACd,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
/**
|
|
5
|
+
* tars logs - Wrapper for pm2 logs tars-supervisor
|
|
6
|
+
*/
|
|
7
|
+
export async function logs() {
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const pm2Path = path.resolve(__dirname, '../../../node_modules/.bin/pm2');
|
|
10
|
+
// Run pm2 logs
|
|
11
|
+
const child = spawn(pm2Path, ['logs', 'tars-supervisor', '--lines', '20'], {
|
|
12
|
+
stdio: 'inherit',
|
|
13
|
+
shell: true
|
|
14
|
+
});
|
|
15
|
+
child.on('error', (err) => {
|
|
16
|
+
// Fallback to npx if relative path fails (though it shouldn't)
|
|
17
|
+
spawn('npx', ['pm2', 'logs', 'tars-supervisor', '--lines', '20'], {
|
|
18
|
+
stdio: 'inherit',
|
|
19
|
+
shell: true
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../../src/cli/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI;IACtB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,gCAAgC,CAAC,CAAC;IAE1E,eAAe;IACf,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,iBAAiB,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE;QACvE,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,IAAI;KACd,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACtB,+DAA+D;QAC/D,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE;YAC9D,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,IAAI;SACd,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function memory(action: string, ...args: string[]): Promise<void>;
|