palmier 0.2.7 → 0.2.8
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/.github/workflows/publish.yml +24 -0
- package/CLAUDE.md +9 -9
- package/README.md +288 -286
- package/dist/agents/shared-prompt.js +16 -16
- package/package.json +44 -36
- package/src/agents/claude.ts +44 -44
- package/src/agents/shared-prompt.ts +28 -28
- package/src/commands/run.ts +619 -619
- package/src/nats-client.ts +15 -15
- package/src/rpc-handler.ts +388 -388
- package/src/types.ts +62 -62
- package/dist/commands/hook.d.ts +0 -7
- package/dist/commands/hook.js +0 -208
- package/dist/commands/task-cleanup.d.ts +0 -14
- package/dist/commands/task-cleanup.js +0 -84
- package/dist/commands/task-generation.md +0 -28
- package/dist/systemd.d.ts +0 -20
- package/dist/systemd.js +0 -145
|
@@ -3,22 +3,22 @@
|
|
|
3
3
|
* Instructs the agent to output structured markers so palmier can determine
|
|
4
4
|
* the task outcome, report files, and permission/input requests.
|
|
5
5
|
*/
|
|
6
|
-
export const AGENT_INSTRUCTIONS = `If you generate report or output files, print each file name on its own line prefixed with [PALMIER_REPORT]: e.g.
|
|
7
|
-
[PALMIER_REPORT] report.md
|
|
8
|
-
[PALMIER_REPORT] summary.md
|
|
9
|
-
|
|
10
|
-
When you are done, output exactly one of these markers as the very last line:
|
|
11
|
-
- Success: [PALMIER_TASK_SUCCESS]
|
|
12
|
-
- Failure: [PALMIER_TASK_FAILURE]
|
|
13
|
-
Do not wrap them in code blocks or add text on the same line.
|
|
14
|
-
|
|
15
|
-
If the task fails because a tool was denied or you lack the required permissions, print each required permission on its own line prefixed with [PALMIER_PERMISSION]: e.g.
|
|
16
|
-
[PALMIER_PERMISSION] Read | Read file contents from the repository
|
|
17
|
-
[PALMIER_PERMISSION] Bash(npm test) | Run the test suite via npm
|
|
18
|
-
[PALMIER_PERMISSION] Write | Write generated output files
|
|
19
|
-
|
|
20
|
-
If the task requires information from the user that you do not have (such as credentials, connection strings, API keys, or configuration values), print each required input on its own line prefixed with [PALMIER_INPUT]: e.g.
|
|
21
|
-
[PALMIER_INPUT] What is the database connection string?
|
|
6
|
+
export const AGENT_INSTRUCTIONS = `If you generate report or output files, print each file name on its own line prefixed with [PALMIER_REPORT]: e.g.
|
|
7
|
+
[PALMIER_REPORT] report.md
|
|
8
|
+
[PALMIER_REPORT] summary.md
|
|
9
|
+
|
|
10
|
+
When you are done, output exactly one of these markers as the very last line:
|
|
11
|
+
- Success: [PALMIER_TASK_SUCCESS]
|
|
12
|
+
- Failure: [PALMIER_TASK_FAILURE]
|
|
13
|
+
Do not wrap them in code blocks or add text on the same line.
|
|
14
|
+
|
|
15
|
+
If the task fails because a tool was denied or you lack the required permissions, print each required permission on its own line prefixed with [PALMIER_PERMISSION]: e.g.
|
|
16
|
+
[PALMIER_PERMISSION] Read | Read file contents from the repository
|
|
17
|
+
[PALMIER_PERMISSION] Bash(npm test) | Run the test suite via npm
|
|
18
|
+
[PALMIER_PERMISSION] Write | Write generated output files
|
|
19
|
+
|
|
20
|
+
If the task requires information from the user that you do not have (such as credentials, connection strings, API keys, or configuration values), print each required input on its own line prefixed with [PALMIER_INPUT]: e.g.
|
|
21
|
+
[PALMIER_INPUT] What is the database connection string?
|
|
22
22
|
[PALMIER_INPUT] What is the API key for the external service?`;
|
|
23
23
|
export const TASK_SUCCESS_MARKER = "[PALMIER_TASK_SUCCESS]";
|
|
24
24
|
export const TASK_FAILURE_MARKER = "[PALMIER_TASK_FAILURE]";
|
package/package.json
CHANGED
|
@@ -1,36 +1,44 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "palmier",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Palmier host CLI - provisions, executes tasks, and serves NATS RPC",
|
|
5
|
-
"license": "Apache-2.0",
|
|
6
|
-
"author": "Hongxu Cai",
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
},
|
|
27
|
-
"
|
|
28
|
-
"@
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "palmier",
|
|
3
|
+
"version": "0.2.8",
|
|
4
|
+
"description": "Palmier host CLI - provisions, executes tasks, and serves NATS RPC",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "Hongxu Cai",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/caihongxu/palmier.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/caihongxu/palmier#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/caihongxu/palmier/issues"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"bin": {
|
|
19
|
+
"palmier": "dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"dev": "tsx src/index.ts",
|
|
23
|
+
"build": "tsc && node -e \"require('fs').cpSync('src/commands/plan-generation.md','dist/commands/plan-generation.md')\"",
|
|
24
|
+
"prepare": "npm run build",
|
|
25
|
+
"start": "node dist/index.js"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
29
|
+
"commander": "^13.1.0",
|
|
30
|
+
"cross-spawn": "^7.0.6",
|
|
31
|
+
"dotenv": "^16.4.7",
|
|
32
|
+
"nats": "^2.29.1",
|
|
33
|
+
"yaml": "^2.7.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/cross-spawn": "^6.0.6",
|
|
37
|
+
"@types/node": "^22.13.0",
|
|
38
|
+
"tsx": "^4.19.0",
|
|
39
|
+
"typescript": "^5.7.0"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=24.0.0"
|
|
43
|
+
}
|
|
44
|
+
}
|
package/src/agents/claude.ts
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
import type { ParsedTask, RequiredPermission } from "../types.js";
|
|
2
|
-
import { execSync } from "child_process";
|
|
3
|
-
import type { AgentTool, CommandLine } from "./agent.js";
|
|
4
|
-
import { AGENT_INSTRUCTIONS } from "./shared-prompt.js";
|
|
5
|
-
|
|
6
|
-
// execSync's shell option takes a string (shell path), not boolean.
|
|
7
|
-
// On Windows we need a shell so .cmd shims resolve correctly.
|
|
8
|
-
const SHELL = process.platform === "win32" ? "cmd.exe" : undefined;
|
|
9
|
-
|
|
10
|
-
export class ClaudeAgent implements AgentTool {
|
|
11
|
-
getPlanGenerationCommandLine(prompt: string): CommandLine {
|
|
12
|
-
return {
|
|
13
|
-
command: "claude",
|
|
14
|
-
args: ["-p", prompt],
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
getTaskRunCommandLine(task: ParsedTask, retryPrompt?: string, extraPermissions?: RequiredPermission[]): CommandLine {
|
|
19
|
-
const prompt = retryPrompt ?? (task.body || task.frontmatter.user_prompt);
|
|
20
|
-
const args = ["--permission-mode", "acceptEdits", "--append-system-prompt", AGENT_INSTRUCTIONS, "-p"];
|
|
21
|
-
|
|
22
|
-
const allPerms = [...(task.frontmatter.permissions ?? []), ...(extraPermissions ?? [])];
|
|
23
|
-
for (const p of allPerms) {
|
|
24
|
-
args.push("--allowedTools", p.name);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (retryPrompt) {args.push("-c");} // continue mode for retries
|
|
28
|
-
return { command: "claude", args, stdin: prompt };
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async init(): Promise<boolean> {
|
|
32
|
-
try {
|
|
33
|
-
execSync("claude --version", { stdio: "ignore", shell: SHELL });
|
|
34
|
-
} catch {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
try {
|
|
38
|
-
execSync("claude mcp add --transport stdio palmier --scope user -- palmier mcpserver", { stdio: "ignore", shell: SHELL });
|
|
39
|
-
} catch {
|
|
40
|
-
// MCP registration is best-effort; agent still works without it
|
|
41
|
-
}
|
|
42
|
-
return true;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
1
|
+
import type { ParsedTask, RequiredPermission } from "../types.js";
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import type { AgentTool, CommandLine } from "./agent.js";
|
|
4
|
+
import { AGENT_INSTRUCTIONS } from "./shared-prompt.js";
|
|
5
|
+
|
|
6
|
+
// execSync's shell option takes a string (shell path), not boolean.
|
|
7
|
+
// On Windows we need a shell so .cmd shims resolve correctly.
|
|
8
|
+
const SHELL = process.platform === "win32" ? "cmd.exe" : undefined;
|
|
9
|
+
|
|
10
|
+
export class ClaudeAgent implements AgentTool {
|
|
11
|
+
getPlanGenerationCommandLine(prompt: string): CommandLine {
|
|
12
|
+
return {
|
|
13
|
+
command: "claude",
|
|
14
|
+
args: ["-p", prompt],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getTaskRunCommandLine(task: ParsedTask, retryPrompt?: string, extraPermissions?: RequiredPermission[]): CommandLine {
|
|
19
|
+
const prompt = retryPrompt ?? (task.body || task.frontmatter.user_prompt);
|
|
20
|
+
const args = ["--permission-mode", "acceptEdits", "--append-system-prompt", AGENT_INSTRUCTIONS, "-p"];
|
|
21
|
+
|
|
22
|
+
const allPerms = [...(task.frontmatter.permissions ?? []), ...(extraPermissions ?? [])];
|
|
23
|
+
for (const p of allPerms) {
|
|
24
|
+
args.push("--allowedTools", p.name);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (retryPrompt) {args.push("-c");} // continue mode for retries
|
|
28
|
+
return { command: "claude", args, stdin: prompt };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async init(): Promise<boolean> {
|
|
32
|
+
try {
|
|
33
|
+
execSync("claude --version", { stdio: "ignore", shell: SHELL });
|
|
34
|
+
} catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
execSync("claude mcp add --transport stdio palmier --scope user -- palmier mcpserver", { stdio: "ignore", shell: SHELL });
|
|
39
|
+
} catch {
|
|
40
|
+
// MCP registration is best-effort; agent still works without it
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Instructions prepended or injected as system prompt for every task invocation.
|
|
3
|
-
* Instructs the agent to output structured markers so palmier can determine
|
|
4
|
-
* the task outcome, report files, and permission/input requests.
|
|
5
|
-
*/
|
|
6
|
-
export const AGENT_INSTRUCTIONS = `If you generate report or output files, print each file name on its own line prefixed with [PALMIER_REPORT]: e.g.
|
|
7
|
-
[PALMIER_REPORT] report.md
|
|
8
|
-
[PALMIER_REPORT] summary.md
|
|
9
|
-
|
|
10
|
-
When you are done, output exactly one of these markers as the very last line:
|
|
11
|
-
- Success: [PALMIER_TASK_SUCCESS]
|
|
12
|
-
- Failure: [PALMIER_TASK_FAILURE]
|
|
13
|
-
Do not wrap them in code blocks or add text on the same line.
|
|
14
|
-
|
|
15
|
-
If the task fails because a tool was denied or you lack the required permissions, print each required permission on its own line prefixed with [PALMIER_PERMISSION]: e.g.
|
|
16
|
-
[PALMIER_PERMISSION] Read | Read file contents from the repository
|
|
17
|
-
[PALMIER_PERMISSION] Bash(npm test) | Run the test suite via npm
|
|
18
|
-
[PALMIER_PERMISSION] Write | Write generated output files
|
|
19
|
-
|
|
20
|
-
If the task requires information from the user that you do not have (such as credentials, connection strings, API keys, or configuration values), print each required input on its own line prefixed with [PALMIER_INPUT]: e.g.
|
|
21
|
-
[PALMIER_INPUT] What is the database connection string?
|
|
22
|
-
[PALMIER_INPUT] What is the API key for the external service?`;
|
|
23
|
-
|
|
24
|
-
export const TASK_SUCCESS_MARKER = "[PALMIER_TASK_SUCCESS]";
|
|
25
|
-
export const TASK_FAILURE_MARKER = "[PALMIER_TASK_FAILURE]";
|
|
26
|
-
export const TASK_REPORT_PREFIX = "[PALMIER_REPORT]";
|
|
27
|
-
export const TASK_PERMISSION_PREFIX = "[PALMIER_PERMISSION]";
|
|
28
|
-
export const TASK_INPUT_PREFIX = "[PALMIER_INPUT]";
|
|
1
|
+
/**
|
|
2
|
+
* Instructions prepended or injected as system prompt for every task invocation.
|
|
3
|
+
* Instructs the agent to output structured markers so palmier can determine
|
|
4
|
+
* the task outcome, report files, and permission/input requests.
|
|
5
|
+
*/
|
|
6
|
+
export const AGENT_INSTRUCTIONS = `If you generate report or output files, print each file name on its own line prefixed with [PALMIER_REPORT]: e.g.
|
|
7
|
+
[PALMIER_REPORT] report.md
|
|
8
|
+
[PALMIER_REPORT] summary.md
|
|
9
|
+
|
|
10
|
+
When you are done, output exactly one of these markers as the very last line:
|
|
11
|
+
- Success: [PALMIER_TASK_SUCCESS]
|
|
12
|
+
- Failure: [PALMIER_TASK_FAILURE]
|
|
13
|
+
Do not wrap them in code blocks or add text on the same line.
|
|
14
|
+
|
|
15
|
+
If the task fails because a tool was denied or you lack the required permissions, print each required permission on its own line prefixed with [PALMIER_PERMISSION]: e.g.
|
|
16
|
+
[PALMIER_PERMISSION] Read | Read file contents from the repository
|
|
17
|
+
[PALMIER_PERMISSION] Bash(npm test) | Run the test suite via npm
|
|
18
|
+
[PALMIER_PERMISSION] Write | Write generated output files
|
|
19
|
+
|
|
20
|
+
If the task requires information from the user that you do not have (such as credentials, connection strings, API keys, or configuration values), print each required input on its own line prefixed with [PALMIER_INPUT]: e.g.
|
|
21
|
+
[PALMIER_INPUT] What is the database connection string?
|
|
22
|
+
[PALMIER_INPUT] What is the API key for the external service?`;
|
|
23
|
+
|
|
24
|
+
export const TASK_SUCCESS_MARKER = "[PALMIER_TASK_SUCCESS]";
|
|
25
|
+
export const TASK_FAILURE_MARKER = "[PALMIER_TASK_FAILURE]";
|
|
26
|
+
export const TASK_REPORT_PREFIX = "[PALMIER_REPORT]";
|
|
27
|
+
export const TASK_PERMISSION_PREFIX = "[PALMIER_PERMISSION]";
|
|
28
|
+
export const TASK_INPUT_PREFIX = "[PALMIER_INPUT]";
|