autohand-cli 0.7.4 → 0.7.6

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/LICENSE CHANGED
@@ -175,47 +175,6 @@
175
175
 
176
176
  END OF TERMS AND CONDITIONS
177
177
 
178
- ============================================================================
179
- COMMERCIAL LICENSE EXCEPTION
180
- ============================================================================
181
-
182
- The Apache License 2.0 above applies to all users EXCEPT as follows:
183
-
184
- If You are a Legal Entity (as defined above) with Annual Recurring Revenue
185
- (ARR) exceeding Five Million United States Dollars (USD $5,000,000), You
186
- must obtain a separate commercial license from the Licensor to use, modify,
187
- or distribute this Work in any form.
188
-
189
- "Annual Recurring Revenue" (ARR) means the annualized value of all
190
- subscription, license, or recurring revenue contracts in effect at the
191
- time of measurement, including but not limited to SaaS subscriptions,
192
- maintenance agreements, and support contracts.
193
-
194
- For commercial licensing inquiries, please contact:
195
-
196
- Autohand AI LLC
197
- Email: licensing@autohand.ai
198
-
199
- This Commercial License Exception does not apply to:
200
- - Individual developers using this Work for personal, non-commercial purposes
201
- - Non-profit organizations
202
- - Educational institutions
203
- - Open source projects licensed under an OSI-approved license
204
- - Legal Entities with ARR of $5,000,000 or less
205
-
206
- ============================================================================
207
-
208
- APPENDIX: How to apply the Apache License to your work.
209
-
210
- To apply the Apache License to your work, attach the following
211
- boilerplate notice, with the fields enclosed by brackets "[]"
212
- replaced with your own identifying information. (Don't include
213
- the brackets!) The text should be enclosed in the appropriate
214
- comment syntax for the file format. We also recommend that a
215
- file or class name and description of purpose be included on the
216
- same "printed page" as the copyright notice for easier
217
- identification within third-party archives.
218
-
219
178
  Copyright 2025 Autohand AI LLC
220
179
 
221
180
  Licensed under the Apache License, Version 2.0 (the "License");
@@ -229,5 +188,3 @@
229
188
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
230
189
  See the License for the specific language governing permissions and
231
190
  limitations under the License.
232
-
233
- Subject to the Commercial License Exception above.
package/README.md CHANGED
@@ -105,6 +105,8 @@ autohand -p "refactor database queries" --dry-run
105
105
  | `--restricted` | | Deny all dangerous operations automatically |
106
106
  | `--config <path>` | | Path to config file |
107
107
  | `--temperature <value>` | | Sampling temperature for LLM |
108
+ | `--login` | | Sign in to your Autohand account |
109
+ | `--logout` | | Sign out of your Autohand account |
108
110
 
109
111
  ## Agent Skills
110
112
 
@@ -328,7 +330,7 @@ docker run -it autohand
328
330
 
329
331
  ## License
330
332
 
331
- **Startup-Friendly License**: Free for startups with ARR under $1M. See [LICENSE](LICENSE) for details.
333
+ Apache License 2.0 - Free for individuals, non-profits, educational institutions, open source projects, and companies with ARR under $5M. See [LICENSE](LICENSE) and [COMMERCIAL.md](COMMERCIAL.md) for details.
332
334
 
333
335
  ## Links
334
336
 
@@ -0,0 +1,9 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+ var _chunk67NJKV5Acjs = require('./chunk-67NJKV5A.cjs');
5
+ require('./chunk-XTHHDIBG.cjs');
6
+
7
+
8
+
9
+ exports.Session = _chunk67NJKV5Acjs.Session; exports.SessionManager = _chunk67NJKV5Acjs.SessionManager;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Session,
3
3
  SessionManager
4
- } from "./chunk-2FLBGPE3.js";
4
+ } from "./chunk-VO3JKFUH.js";
5
5
  import "./chunk-FUEL6BK7.js";
6
6
  export {
7
7
  Session,
@@ -0,0 +1,151 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+ var _chunkXTHHDIBGcjs = require('./chunk-XTHHDIBG.cjs');
4
+
5
+ // src/commands/resume.ts
6
+ var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
7
+ var _enquirer = require('enquirer'); var _enquirer2 = _interopRequireDefault(_enquirer);
8
+ var _fsextra = require('fs-extra'); var _fsextra2 = _interopRequireDefault(_fsextra);
9
+ var _path = require('path'); var _path2 = _interopRequireDefault(_path);
10
+ var metadata = {
11
+ command: "/resume",
12
+ description: "resume a previous session",
13
+ implemented: true
14
+ };
15
+ async function getSessionTitle(sessionMeta) {
16
+ if (sessionMeta.summary && sessionMeta.summary.trim()) {
17
+ return sessionMeta.summary.slice(0, 60);
18
+ }
19
+ try {
20
+ const conversationPath = _path2.default.join(_chunkXTHHDIBGcjs.AUTOHAND_PATHS.sessions, sessionMeta.sessionId, "conversation.jsonl");
21
+ if (await _fsextra2.default.pathExists(conversationPath)) {
22
+ const content = await _fsextra2.default.readFile(conversationPath, "utf-8");
23
+ const lines = content.trim().split("\n").filter((line) => line);
24
+ for (const line of lines) {
25
+ try {
26
+ const msg = JSON.parse(line);
27
+ if (msg.role === "user" && msg.content) {
28
+ const cleanContent = msg.content.replace(/\n/g, " ").replace(/\s+/g, " ").trim();
29
+ return cleanContent.slice(0, 60) + (cleanContent.length > 60 ? "..." : "");
30
+ }
31
+ } catch (e) {
32
+ }
33
+ }
34
+ }
35
+ } catch (e2) {
36
+ }
37
+ return _chalk2.default.gray("(no title)");
38
+ }
39
+ function formatSessionChoice(sessionMeta, title) {
40
+ const date = new Date(sessionMeta.createdAt);
41
+ const timeAgo = getTimeAgo(date);
42
+ const msgCount = sessionMeta.messageCount;
43
+ return {
44
+ name: sessionMeta.sessionId,
45
+ message: title,
46
+ hint: `${timeAgo} - ${msgCount} messages - ${sessionMeta.projectName}`
47
+ };
48
+ }
49
+ function getTimeAgo(date) {
50
+ const now = /* @__PURE__ */ new Date();
51
+ const diffMs = now.getTime() - date.getTime();
52
+ const diffMins = Math.floor(diffMs / (1e3 * 60));
53
+ const diffHours = Math.floor(diffMs / (1e3 * 60 * 60));
54
+ const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
55
+ if (diffMins < 1) return "just now";
56
+ if (diffMins < 60) return `${diffMins}m ago`;
57
+ if (diffHours < 24) return `${diffHours}h ago`;
58
+ if (diffDays < 7) return `${diffDays}d ago`;
59
+ return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
60
+ }
61
+ async function resume(ctx) {
62
+ const sessionId = ctx.args[0];
63
+ if (sessionId) {
64
+ return resumeSession(ctx.sessionManager, sessionId);
65
+ }
66
+ try {
67
+ const allSessions = await ctx.sessionManager.listSessions();
68
+ if (allSessions.length === 0) {
69
+ console.log(_chalk2.default.gray("\nNo sessions found."));
70
+ console.log(_chalk2.default.gray("Start a new conversation to create a session.\n"));
71
+ return null;
72
+ }
73
+ console.log(_chalk2.default.cyan("\nSelect a session to resume:\n"));
74
+ const choices = [];
75
+ const recentSessions = allSessions.slice(0, 20);
76
+ for (const session of recentSessions) {
77
+ const title = await getSessionTitle(session);
78
+ choices.push(formatSessionChoice(session, title));
79
+ }
80
+ if (allSessions.length > 20) {
81
+ choices.push({
82
+ name: "__more__",
83
+ message: _chalk2.default.gray(`... ${allSessions.length - 20} more sessions`),
84
+ hint: "Use /sessions to see all"
85
+ });
86
+ }
87
+ const { selected } = await _enquirer2.default.prompt([
88
+ {
89
+ type: "select",
90
+ name: "selected",
91
+ message: "Choose a session",
92
+ choices
93
+ }
94
+ ]);
95
+ if (selected === "__more__") {
96
+ console.log(_chalk2.default.gray("\nUse /sessions to see all sessions, then /resume <id>"));
97
+ return null;
98
+ }
99
+ return resumeSession(ctx.sessionManager, selected);
100
+ } catch (error) {
101
+ if (error.name === "ExitPromptError" || _optionalChain([error, 'access', _ => _.message, 'optionalAccess', _2 => _2.includes, 'call', _3 => _3("canceled")])) {
102
+ console.log(_chalk2.default.gray("\nResume cancelled."));
103
+ return null;
104
+ }
105
+ console.error(_chalk2.default.red(`Failed to list sessions: ${error.message}`));
106
+ return null;
107
+ }
108
+ }
109
+ async function resumeSession(sessionManager, sessionId) {
110
+ try {
111
+ const session = await sessionManager.loadSession(sessionId);
112
+ const messages = session.getMessages();
113
+ const firstUserMessage = messages.find((m) => m.role === "user");
114
+ const title = session.metadata.summary || _optionalChain([firstUserMessage, 'optionalAccess', _4 => _4.content, 'access', _5 => _5.slice, 'call', _6 => _6(0, 50)]) || "Untitled session";
115
+ console.log(_chalk2.default.cyan(`
116
+ Resuming: ${title}`));
117
+ console.log(_chalk2.default.gray(` Project: ${session.metadata.projectPath}`));
118
+ console.log(_chalk2.default.gray(` Started: ${new Date(session.metadata.createdAt).toLocaleString()}`));
119
+ console.log(_chalk2.default.gray(` Messages: ${messages.length}`));
120
+ console.log();
121
+ if (messages.length > 0) {
122
+ console.log(_chalk2.default.cyan("Recent conversation:"));
123
+ console.log(_chalk2.default.gray("\u2500".repeat(60)));
124
+ const recentMessages = messages.slice(-5);
125
+ for (const msg of recentMessages) {
126
+ const role = msg.role === "user" ? _chalk2.default.green("You") : msg.role === "assistant" ? _chalk2.default.blue("Assistant") : _chalk2.default.gray(msg.role);
127
+ if (msg.role === "tool") continue;
128
+ const preview = msg.content.replace(/\n/g, " ").replace(/\s+/g, " ").slice(0, 100);
129
+ const truncated = msg.content.length > 100 ? "..." : "";
130
+ console.log(`${role}: ${_chalk2.default.white(preview)}${truncated}`);
131
+ }
132
+ console.log(_chalk2.default.gray("\u2500".repeat(60)));
133
+ console.log();
134
+ }
135
+ console.log(_chalk2.default.green("Session resumed. Continue typing to chat.\n"));
136
+ return "SESSION_RESUMED";
137
+ } catch (error) {
138
+ console.error(_chalk2.default.red(`Failed to resume session: ${error.message}`));
139
+ return null;
140
+ }
141
+ }
142
+
143
+
144
+
145
+
146
+ exports.metadata = metadata; exports.resume = resume;
147
+ /**
148
+ * @license
149
+ * Copyright 2025 Autohand AI LLC
150
+ * SPDX-License-Identifier: Apache-2.0
151
+ */
@@ -1,106 +1,10 @@
1
+ import {
2
+ package_default
3
+ } from "./chunk-5MCDN53U.js";
4
+
1
5
  // src/commands/status.ts
2
6
  import chalk from "chalk";
3
7
  import readline from "readline";
4
-
5
- // package.json
6
- var package_default = {
7
- name: "autohand-cli",
8
- version: "0.7.4",
9
- licenses: "SEE LICENSE IN LICENSE",
10
- description: "Autohand interactive coding agent CLI powered by LLMs.",
11
- repository: {
12
- type: "git",
13
- url: "https://github.com/autohandai/code-cli.git"
14
- },
15
- homepage: "https://autohand.ai/cli/",
16
- bugs: {
17
- url: "https://github.com/autohandai/code-cli/issues"
18
- },
19
- type: "module",
20
- bin: {
21
- autohand: "dist/index.js"
22
- },
23
- main: "dist/index.js",
24
- files: [
25
- "dist"
26
- ],
27
- scripts: {
28
- go: 'bun run build && ./install-local.sh && echo "COMPLETED"',
29
- build: "tsup",
30
- dev: "bun src/index.ts",
31
- typecheck: "tsc --noEmit",
32
- lint: "eslint .",
33
- test: "vitest run",
34
- start: "node dist/index.js",
35
- "compile:macos-arm64": "bun build ./src/index.ts --compile --target=bun-darwin-arm64 --external react-devtools-core --outfile ./binaries/autohand-macos-arm64",
36
- "compile:macos-x64": "bun build ./src/index.ts --compile --target=bun-darwin-x64 --external react-devtools-core --outfile ./binaries/autohand-macos-x64",
37
- "compile:linux-x64": "bun build ./src/index.ts --compile --target=bun-linux-x64 --external react-devtools-core --outfile ./binaries/autohand-linux-x64",
38
- "compile:linux-arm64": "bun build ./src/index.ts --compile --target=bun-linux-arm64 --external react-devtools-core --outfile ./binaries/autohand-linux-arm64",
39
- "compile:windows-x64": "bun build ./src/index.ts --compile --target=bun-windows-x64 --external react-devtools-core --outfile ./binaries/autohand-windows-x64.exe",
40
- "compile:all": "bun run compile:macos-arm64 && bun run compile:macos-x64 && bun run compile:linux-x64 && bun run compile:linux-arm64 && bun run compile:windows-x64",
41
- link: "bun link"
42
- },
43
- keywords: [
44
- "cli",
45
- "llm",
46
- "agent",
47
- "autohand"
48
- ],
49
- engines: {
50
- node: ">=18.17.0"
51
- },
52
- dependencies: {
53
- chalk: "^5.6.2",
54
- commander: "^14.0.2",
55
- diff: "^8.0.2",
56
- dotenv: "^17.2.3",
57
- enquirer: "^2.4.1",
58
- "fs-extra": "^11.3.2",
59
- ignore: "^5.3.1",
60
- ink: "^4.4.1",
61
- "ink-spinner": "^5.0.0",
62
- minimatch: "^10.1.1",
63
- open: "^10.1.0",
64
- ora: "^9.0.0",
65
- react: "^18.2.0",
66
- "react-devtools-core": "^7.0.1",
67
- "terminal-link": "^3.0.0",
68
- yaml: "^2.8.2",
69
- zod: "^4.1.12"
70
- },
71
- devDependencies: {
72
- "@types/diff": "^8.0.0",
73
- "@types/fs-extra": "^11.0.4",
74
- "@types/minimatch": "^6.0.0",
75
- "@types/node": "^24.10.1",
76
- "@types/react": "^18.3.3",
77
- "@types/terminal-link": "^1.2.0",
78
- "@typescript-eslint/eslint-plugin": "^8.48.1",
79
- "@typescript-eslint/parser": "^8.48.1",
80
- eslint: "^9.39.1",
81
- tsup: "^8.5.1",
82
- tsx: "^4.20.6",
83
- typescript: "^5.9.3",
84
- vitest: "^1.6.0"
85
- },
86
- overrides: {
87
- ink: {
88
- "slice-ansi": {
89
- "ansi-styles": "^6.2.1"
90
- },
91
- "wrap-ansi": {
92
- "ansi-styles": "^6.2.1"
93
- },
94
- "cli-truncate": {
95
- "slice-ansi": {
96
- "ansi-styles": "^6.2.1"
97
- }
98
- }
99
- }
100
- }
101
- };
102
-
103
- // src/commands/status.ts
104
8
  var metadata = {
105
9
  command: "/status",
106
10
  description: "Show Autohand status including version, model, API connectivity, and usage",
@@ -304,7 +208,6 @@ function formatTokens(tokens) {
304
208
  }
305
209
 
306
210
  export {
307
- package_default,
308
211
  metadata,
309
212
  status
310
213
  };
@@ -0,0 +1,102 @@
1
+ // package.json
2
+ var package_default = {
3
+ name: "autohand-cli",
4
+ version: "0.7.6",
5
+ license: "Apache-2.0",
6
+ description: "Autohand interactive coding agent CLI powered by LLMs.",
7
+ repository: {
8
+ type: "git",
9
+ url: "https://github.com/autohandai/code-cli.git"
10
+ },
11
+ homepage: "https://autohand.ai/cli/",
12
+ bugs: {
13
+ url: "https://github.com/autohandai/code-cli/issues"
14
+ },
15
+ type: "module",
16
+ bin: {
17
+ autohand: "dist/index.js"
18
+ },
19
+ main: "dist/index.js",
20
+ files: [
21
+ "dist"
22
+ ],
23
+ scripts: {
24
+ go: 'bun run build && ./install-local.sh && echo "COMPLETED"',
25
+ build: "tsup",
26
+ dev: "bun src/index.ts",
27
+ typecheck: "tsc --noEmit",
28
+ lint: "eslint .",
29
+ test: "vitest run",
30
+ start: "node dist/index.js",
31
+ "compile:macos-arm64": "bun build ./src/index.ts --compile --target=bun-darwin-arm64 --external react-devtools-core --outfile ./binaries/autohand-macos-arm64",
32
+ "compile:macos-x64": "bun build ./src/index.ts --compile --target=bun-darwin-x64 --external react-devtools-core --outfile ./binaries/autohand-macos-x64",
33
+ "compile:linux-x64": "bun build ./src/index.ts --compile --target=bun-linux-x64 --external react-devtools-core --outfile ./binaries/autohand-linux-x64",
34
+ "compile:linux-arm64": "bun build ./src/index.ts --compile --target=bun-linux-arm64 --external react-devtools-core --outfile ./binaries/autohand-linux-arm64",
35
+ "compile:windows-x64": "bun build ./src/index.ts --compile --target=bun-windows-x64 --external react-devtools-core --outfile ./binaries/autohand-windows-x64.exe",
36
+ "compile:all": "bun run compile:macos-arm64 && bun run compile:macos-x64 && bun run compile:linux-x64 && bun run compile:linux-arm64 && bun run compile:windows-x64",
37
+ link: "bun link"
38
+ },
39
+ keywords: [
40
+ "cli",
41
+ "llm",
42
+ "agent",
43
+ "autohand"
44
+ ],
45
+ engines: {
46
+ node: ">=18.17.0"
47
+ },
48
+ dependencies: {
49
+ chalk: "^5.6.2",
50
+ commander: "^14.0.2",
51
+ diff: "^8.0.2",
52
+ dotenv: "^17.2.3",
53
+ enquirer: "^2.4.1",
54
+ "fs-extra": "^11.3.2",
55
+ ignore: "^5.3.1",
56
+ ink: "^4.4.1",
57
+ "ink-spinner": "^5.0.0",
58
+ minimatch: "^10.1.1",
59
+ open: "^10.1.0",
60
+ ora: "^9.0.0",
61
+ react: "^18.2.0",
62
+ "react-devtools-core": "^7.0.1",
63
+ "terminal-link": "^3.0.0",
64
+ yaml: "^2.8.2",
65
+ zod: "^4.1.12"
66
+ },
67
+ devDependencies: {
68
+ "@types/diff": "^8.0.0",
69
+ "@types/fs-extra": "^11.0.4",
70
+ "@types/minimatch": "^6.0.0",
71
+ "@types/node": "^24.10.1",
72
+ "@types/react": "^18.3.3",
73
+ "@types/terminal-link": "^1.2.0",
74
+ "@typescript-eslint/eslint-plugin": "^8.48.1",
75
+ "@typescript-eslint/parser": "^8.48.1",
76
+ eslint: "^9.39.1",
77
+ memfs: "^4.51.1",
78
+ tsup: "^8.5.1",
79
+ tsx: "^4.20.6",
80
+ typescript: "^5.9.3",
81
+ vitest: "^1.6.0"
82
+ },
83
+ overrides: {
84
+ ink: {
85
+ "slice-ansi": {
86
+ "ansi-styles": "^6.2.1"
87
+ },
88
+ "wrap-ansi": {
89
+ "ansi-styles": "^6.2.1"
90
+ },
91
+ "cli-truncate": {
92
+ "slice-ansi": {
93
+ "ansi-styles": "^6.2.1"
94
+ }
95
+ }
96
+ }
97
+ }
98
+ };
99
+
100
+ export {
101
+ package_default
102
+ };
@@ -20,6 +20,8 @@ var SessionManager = class {
20
20
  const sessionId = this.generateSessionId();
21
21
  const sessionDir = _path2.default.join(this.sessionsDir, sessionId);
22
22
  await _fsextra2.default.ensureDir(sessionDir);
23
+ const client = process.env.AUTOHAND_CLIENT_NAME || "terminal";
24
+ const clientVersion = process.env.AUTOHAND_CLIENT_VERSION;
23
25
  const metadata = {
24
26
  sessionId,
25
27
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -28,7 +30,9 @@ var SessionManager = class {
28
30
  projectName: _path2.default.basename(projectPath),
29
31
  model,
30
32
  messageCount: 0,
31
- status: "active"
33
+ status: "active",
34
+ client,
35
+ clientVersion
32
36
  };
33
37
  const session = new Session(sessionDir, metadata);
34
38
  await session.save();