shiva-code 0.7.3 → 0.7.5

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 ADDED
@@ -0,0 +1,211 @@
1
+ # SHIVA Code CLI
2
+
3
+ > Makes Claude Code Persistent - Cross-Project Memory for AI Coding
4
+
5
+ [![npm version](https://badge.fury.io/js/shiva-code.svg)](https://www.npmjs.com/package/shiva-code)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Features
9
+
10
+ - **Persistent Memory** - Memories survive across sessions and projects
11
+ - **Cloud Sync** - Sync your data between devices
12
+ - **Project Packages** - Launch multiple projects at once
13
+ - **Secure Secrets** - Encrypted secret storage with vault
14
+ - **Docker Support** - Isolated development environments
15
+ - **GitHub Integration** - Issues, PRs, and context at your fingertips
16
+ - **Session Management** - Resume, restore, and organize sessions
17
+
18
+ ## Installation
19
+
20
+ ### Native Binary (Recommended)
21
+
22
+ ```bash
23
+ curl -fsSL https://shiva.li/install | bash
24
+ ```
25
+
26
+ ### npm
27
+
28
+ ```bash
29
+ npm install -g shiva-code
30
+ ```
31
+
32
+ ### From Source
33
+
34
+ ```bash
35
+ git clone https://github.com/Aimtaim/shiva-code.git
36
+ cd shiva-code
37
+ npm install
38
+ npm run build
39
+ npm link
40
+ ```
41
+
42
+ ## Quick Start
43
+
44
+ ```bash
45
+ # Initialize project
46
+ cd your-project
47
+ shiva init
48
+
49
+ # Save a memory
50
+ shiva remember "User prefers TypeScript" --category preference
51
+
52
+ # Search memories
53
+ shiva search "typescript"
54
+
55
+ # Start Claude with context
56
+ claude
57
+ ```
58
+
59
+ ## Commands
60
+
61
+ ### Session Management
62
+
63
+ | Command | Alias | Description |
64
+ |---------|-------|-------------|
65
+ | `shiva sessions` | `ss` | List all Claude sessions |
66
+ | `shiva resume` | `res` | Resume a session |
67
+ | `shiva restore` | `rst` | Restore a crashed session |
68
+ | `shiva start` | `st` | Start multiple projects |
69
+
70
+ ### Memory & Context
71
+
72
+ | Command | Alias | Description |
73
+ |---------|-------|-------------|
74
+ | `shiva remember` | `rem`, `r` | Save a memory |
75
+ | `shiva search` | `s`, `find` | Search memories |
76
+ | `shiva forget` | `fg` | Delete a memory |
77
+ | `shiva context` | - | Show current context |
78
+ | `shiva tags` | - | Manage session tags |
79
+ | `shiva export` | - | Export sessions |
80
+ | `shiva import` | - | Import sessions |
81
+
82
+ ### Project Management
83
+
84
+ | Command | Alias | Description |
85
+ |---------|-------|-------------|
86
+ | `shiva init` | `i` | Initialize a project |
87
+ | `shiva sync` | `sy` | Sync with cloud |
88
+ | `shiva status` | `stat` | Show project status |
89
+ | `shiva projects` | `proj`, `p` | List all projects |
90
+ | `shiva config` | `cfg` | Manage settings |
91
+
92
+ ### GitHub Integration
93
+
94
+ | Command | Alias | Description |
95
+ |---------|-------|-------------|
96
+ | `shiva github` | `gh` | GitHub status/login |
97
+ | `shiva issues` | `iss` | Show GitHub issues |
98
+ | `shiva prs` | `pr` | Show pull requests |
99
+
100
+ ### Security
101
+
102
+ | Command | Alias | Description |
103
+ |---------|-------|-------------|
104
+ | `shiva secrets` | `sec` | Manage secrets |
105
+ | `shiva scan` | `sc` | Security scan |
106
+
107
+ ### Advanced
108
+
109
+ | Command | Alias | Description |
110
+ |---------|-------|-------------|
111
+ | `shiva package` | `pkg` | Manage project packages |
112
+ | `shiva docker` | `dk` | Docker mode |
113
+ | `shiva sandbox` | `sb` | Sandbox mode |
114
+ | `shiva workflow` | `wf` | Manage workflows |
115
+ | `shiva hook` | `hk` | Manage hooks |
116
+
117
+ ### System
118
+
119
+ | Command | Alias | Description |
120
+ |---------|-------|-------------|
121
+ | `shiva doctor` | `doc` | System check |
122
+ | `shiva upgrade` | `up` | Update SHIVA |
123
+ | `shiva stats` | - | Show analytics |
124
+ | `shiva validate` | - | Validate configuration |
125
+
126
+ ## Debug Mode
127
+
128
+ Enable debug mode for troubleshooting:
129
+
130
+ ```bash
131
+ # Via flag
132
+ shiva --debug status
133
+
134
+ # Via environment variable
135
+ SHIVA_DEBUG=1 shiva status
136
+ ```
137
+
138
+ ## Configuration
139
+
140
+ SHIVA stores configuration in `~/.config/shiva-code/`:
141
+
142
+ - `config.json` - Main configuration
143
+ - `packages.json` - Package definitions
144
+ - `secrets.json` - Encrypted secrets (local)
145
+
146
+ Project-specific settings are stored in `.shiva/`:
147
+
148
+ - `config.json` - Project configuration
149
+ - `CLAUDE.md` - Claude context file
150
+
151
+ ## Environment Variables
152
+
153
+ | Variable | Description |
154
+ |----------|-------------|
155
+ | `SHIVA_DEBUG` | Enable debug mode (`1` to enable) |
156
+ | `SHIVA_API_URL` | Override API endpoint |
157
+ | `SHIVA_TOKEN` | Authentication token |
158
+
159
+ ## CLAUDE.md Integration
160
+
161
+ SHIVA automatically manages your `CLAUDE.md` file, which Claude Code uses for context. The file includes:
162
+
163
+ - Project information
164
+ - Saved memories
165
+ - Tech stack details
166
+ - Custom instructions
167
+
168
+ ## Documentation
169
+
170
+ - [Getting Started](https://shiva.li/docs)
171
+ - [Commands Reference](https://shiva.li/docs/commands)
172
+ - [API Documentation](https://shiva.li/docs/api)
173
+ - [FAQ](https://shiva.li/docs/faq)
174
+
175
+ ## Development
176
+
177
+ ```bash
178
+ # Install dependencies
179
+ npm install
180
+
181
+ # Build
182
+ npm run build
183
+
184
+ # Run tests
185
+ npm test
186
+
187
+ # Run tests with coverage
188
+ npm run test:coverage
189
+
190
+ # Type check
191
+ npm run typecheck
192
+
193
+ # Development mode (watch)
194
+ npm run dev
195
+ ```
196
+
197
+ ## Contributing
198
+
199
+ Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details.
200
+
201
+ ## License
202
+
203
+ MIT - see [LICENSE](LICENSE) for details.
204
+
205
+ ## Links
206
+
207
+ - [Website](https://shiva.li)
208
+ - [Documentation](https://shiva.li/docs)
209
+ - [GitHub](https://github.com/Aimtaim/shiva-code)
210
+ - [npm](https://www.npmjs.com/package/shiva-code)
211
+ - [Report Issues](https://github.com/Aimtaim/shiva-code/issues)
@@ -3,6 +3,29 @@ import {
3
3
  getToken
4
4
  } from "./chunk-OP4HYQZZ.js";
5
5
 
6
+ // src/utils/debug.ts
7
+ var debugEnabled = false;
8
+ function isDebugEnabled() {
9
+ return debugEnabled || process.env.SHIVA_DEBUG === "1";
10
+ }
11
+ function enableDebug() {
12
+ debugEnabled = true;
13
+ }
14
+ function debug(message, data) {
15
+ if (!isDebugEnabled()) return;
16
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
17
+ console.error(`[DEBUG ${timestamp}] ${message}`);
18
+ if (data !== void 0) {
19
+ console.error(JSON.stringify(data, null, 2));
20
+ }
21
+ }
22
+ function debugApi(method, url, status, duration) {
23
+ if (!isDebugEnabled()) return;
24
+ const statusStr = status ? ` -> ${status}` : "";
25
+ const durationStr = duration ? ` (${duration}ms)` : "";
26
+ debug(`API: ${method} ${url}${statusStr}${durationStr}`);
27
+ }
28
+
6
29
  // src/services/api/client.ts
7
30
  var ApiClient = class {
8
31
  getHeaders() {
@@ -18,6 +41,8 @@ var ApiClient = class {
18
41
  async request(endpoint, options = {}) {
19
42
  const baseUrl = getApiEndpoint();
20
43
  const url = `${baseUrl}${endpoint}`;
44
+ const method = options.method || "GET";
45
+ const startTime = Date.now();
21
46
  const response = await fetch(url, {
22
47
  ...options,
23
48
  headers: {
@@ -25,6 +50,8 @@ var ApiClient = class {
25
50
  ...options.headers
26
51
  }
27
52
  });
53
+ const duration = Date.now() - startTime;
54
+ debugApi(method, endpoint, response.status, duration);
28
55
  if (!response.ok) {
29
56
  const error = await response.json().catch(() => ({ error: "Unknown error" }));
30
57
  throw new Error(error.error || error.message || `HTTP ${response.status}`);
@@ -799,5 +826,6 @@ var ApiClient = class {
799
826
  var api = new ApiClient();
800
827
 
801
828
  export {
829
+ enableDebug,
802
830
  api
803
831
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  findProject,
3
3
  getProjectName
4
- } from "./chunk-H5OFO4VS.js";
4
+ } from "./chunk-W3DKHCXB.js";
5
5
 
6
6
  // src/services/data/package-manager.ts
7
7
  import Conf from "conf";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-Z6NXFC4Q.js";
5
5
  import {
6
6
  api
7
- } from "./chunk-QQZRCJZK.js";
7
+ } from "./chunk-J5IS642F.js";
8
8
  import {
9
9
  clearAuth,
10
10
  getConfig,
@@ -1589,7 +1589,7 @@ hookCommand.command("branch-switch").description("Branch-Wechsel behandeln (f\xF
1589
1589
  }
1590
1590
  const { getCurrentBranch } = await import("./api-OEHQTBH7.js");
1591
1591
  const { getSessionForBranch, hasShivaDir: hasShivaDir2 } = await import("./config-D6M6LI6U.js");
1592
- const { findProject, findSessionByBranch, formatRelativeTime } = await import("./manager-ZPQWG7E6.js");
1592
+ const { findProject, findSessionByBranch, formatRelativeTime } = await import("./manager-CCRAV6A5.js");
1593
1593
  const projectPath = process.cwd();
1594
1594
  const newBranch = getCurrentBranch(projectPath);
1595
1595
  let sessionInfo = null;
@@ -1659,7 +1659,7 @@ hookCommand.command("scan-command").description("Scanne Bash-Befehle auf Package
1659
1659
  }
1660
1660
  });
1661
1661
  hookCommand.command("push").description("Hooks in Cloud sichern").action(async () => {
1662
- const { api } = await import("./client-GIGZFXT5.js");
1662
+ const { api } = await import("./client-RPSJP4Z5.js");
1663
1663
  const { isAuthenticated } = await import("./config-FGMZONWV.js");
1664
1664
  if (!isAuthenticated()) {
1665
1665
  log.error("Nicht angemeldet");
@@ -1679,7 +1679,7 @@ hookCommand.command("push").description("Hooks in Cloud sichern").action(async (
1679
1679
  }
1680
1680
  });
1681
1681
  hookCommand.command("pull").description("Hooks aus Cloud laden").option("-f, --force", "Lokale Hooks \xFCberschreiben").action(async (options) => {
1682
- const { api } = await import("./client-GIGZFXT5.js");
1682
+ const { api } = await import("./client-RPSJP4Z5.js");
1683
1683
  const { isAuthenticated } = await import("./config-FGMZONWV.js");
1684
1684
  if (!isAuthenticated()) {
1685
1685
  log.error("Nicht angemeldet");
@@ -1711,7 +1711,7 @@ hookCommand.command("pull").description("Hooks aus Cloud laden").option("-f, --f
1711
1711
  }
1712
1712
  });
1713
1713
  hookCommand.command("sync").description("Hooks mit Cloud synchronisieren").action(async () => {
1714
- const { api } = await import("./client-GIGZFXT5.js");
1714
+ const { api } = await import("./client-RPSJP4Z5.js");
1715
1715
  const { isAuthenticated } = await import("./config-FGMZONWV.js");
1716
1716
  if (!isAuthenticated()) {
1717
1717
  log.error("Nicht angemeldet");
@@ -1738,7 +1738,7 @@ hookCommand.command("sync").description("Hooks mit Cloud synchronisieren").actio
1738
1738
  }
1739
1739
  });
1740
1740
  hookCommand.command("cloud-list").description("Cloud-Hooks auflisten").option("--event <type>", "Nach Event-Typ filtern").option("--json", "JSON Output").action(async (options) => {
1741
- const { api } = await import("./client-GIGZFXT5.js");
1741
+ const { api } = await import("./client-RPSJP4Z5.js");
1742
1742
  const { isAuthenticated } = await import("./config-FGMZONWV.js");
1743
1743
  const { colors } = await import("./logger-E7SC5KUO.js");
1744
1744
  if (!isAuthenticated()) {
@@ -1787,7 +1787,7 @@ hookCommand.command("cloud-list").description("Cloud-Hooks auflisten").option("-
1787
1787
  }
1788
1788
  });
1789
1789
  hookCommand.command("cloud-create").description("Neuen Cloud-Hook erstellen").requiredOption("--event <event>", "Event-Typ (PreToolUse, PostToolUse, etc.)").requiredOption("--command <cmd>", "Auszuf\xFChrender Befehl").option("--matcher <pattern>", "Tool-Matcher Pattern").option("--type <type>", "Hook-Typ (command, script)", "command").option("--timeout <ms>", "Timeout in Millisekunden").action(async (options) => {
1790
- const { api } = await import("./client-GIGZFXT5.js");
1790
+ const { api } = await import("./client-RPSJP4Z5.js");
1791
1791
  const { isAuthenticated } = await import("./config-FGMZONWV.js");
1792
1792
  if (!isAuthenticated()) {
1793
1793
  log.error("Nicht angemeldet");
@@ -1815,7 +1815,7 @@ hookCommand.command("cloud-create").description("Neuen Cloud-Hook erstellen").re
1815
1815
  }
1816
1816
  });
1817
1817
  hookCommand.command("cloud-test").description("Cloud-Hook testen").argument("<hook-id>", "Hook ID").action(async (hookId) => {
1818
- const { api } = await import("./client-GIGZFXT5.js");
1818
+ const { api } = await import("./client-RPSJP4Z5.js");
1819
1819
  const { isAuthenticated } = await import("./config-FGMZONWV.js");
1820
1820
  const { colors } = await import("./logger-E7SC5KUO.js");
1821
1821
  if (!isAuthenticated()) {
@@ -1850,7 +1850,7 @@ hookCommand.command("cloud-test").description("Cloud-Hook testen").argument("<ho
1850
1850
  }
1851
1851
  });
1852
1852
  hookCommand.command("cloud-delete").description("Cloud-Hook l\xF6schen").argument("<hook-id>", "Hook ID").option("-y, --yes", "Ohne Best\xE4tigung").action(async (hookId, options) => {
1853
- const { api } = await import("./client-GIGZFXT5.js");
1853
+ const { api } = await import("./client-RPSJP4Z5.js");
1854
1854
  const { isAuthenticated } = await import("./config-FGMZONWV.js");
1855
1855
  if (!isAuthenticated()) {
1856
1856
  log.error("Nicht angemeldet");
@@ -1885,7 +1885,7 @@ hookCommand.command("cloud-delete").description("Cloud-Hook l\xF6schen").argumen
1885
1885
  }
1886
1886
  });
1887
1887
  hookCommand.command("cloud-toggle").description("Cloud-Hook aktivieren/deaktivieren").argument("<hook-id>", "Hook ID").option("--enable", "Hook aktivieren").option("--disable", "Hook deaktivieren").action(async (hookId, options) => {
1888
- const { api } = await import("./client-GIGZFXT5.js");
1888
+ const { api } = await import("./client-RPSJP4Z5.js");
1889
1889
  const { isAuthenticated } = await import("./config-FGMZONWV.js");
1890
1890
  if (!isAuthenticated()) {
1891
1891
  log.error("Nicht angemeldet");
@@ -43,6 +43,10 @@ function isPathWithinAllowedBoundaries(inputPath) {
43
43
  ];
44
44
  return allowedPrefixes.some((prefix) => resolved.startsWith(prefix));
45
45
  }
46
+ var SHELL_DANGEROUS_CHARS = /[;&|`$(){}[\]<>\\!#*?"'\n\r\t]/;
47
+ function containsShellMetacharacters(input) {
48
+ return SHELL_DANGEROUS_CHARS.test(input);
49
+ }
46
50
  function isValidSessionId(sessionId) {
47
51
  if (!sessionId || typeof sessionId !== "string") {
48
52
  return false;
@@ -402,6 +406,7 @@ function formatDate(date) {
402
406
  }
403
407
 
404
408
  export {
409
+ containsShellMetacharacters,
405
410
  isValidSessionId,
406
411
  isValidProjectPath,
407
412
  maskSecret,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  api
3
- } from "./chunk-QQZRCJZK.js";
3
+ } from "./chunk-J5IS642F.js";
4
4
  import "./chunk-OP4HYQZZ.js";
5
5
  import "./chunk-3RG5ZIWI.js";
6
6
  export {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  hookCommand
3
- } from "./chunk-UAP4ZKEJ.js";
3
+ } from "./chunk-RQ75X32M.js";
4
4
  import "./chunk-Z6NXFC4Q.js";
5
5
  import "./chunk-IVFCZLBX.js";
6
6
  import "./chunk-PMA6MGQW.js";