@ngandu/ulicode 0.0.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/CHANGELOG.md +1081 -0
- package/README.md +312 -0
- package/dist/agents/definitions/ask.agent.md +53 -0
- package/dist/agents/definitions/audit-tests.agent.md +138 -0
- package/dist/agents/definitions/build.agent.md +111 -0
- package/dist/agents/definitions/execute.agent.md +99 -0
- package/dist/agents/definitions/explore.agent.md +57 -0
- package/dist/agents/definitions/fast.agent.md +48 -0
- package/dist/agents/definitions/plan-mode.agent.md +102 -0
- package/dist/agents/definitions/planner.agent.md +59 -0
- package/dist/chunk-3YYDXNUH.js +854 -0
- package/dist/chunk-3YYDXNUH.js.map +1 -0
- package/dist/chunk-IEV2IT3O.cjs +873 -0
- package/dist/chunk-IEV2IT3O.cjs.map +1 -0
- package/dist/chunk-MBWGSXBT.js +11927 -0
- package/dist/chunk-MBWGSXBT.js.map +1 -0
- package/dist/chunk-MS5RYNRK.js +137 -0
- package/dist/chunk-MS5RYNRK.js.map +1 -0
- package/dist/chunk-OXFO76JC.js +2633 -0
- package/dist/chunk-OXFO76JC.js.map +1 -0
- package/dist/chunk-PKRLG6A4.js +1756 -0
- package/dist/chunk-PKRLG6A4.js.map +1 -0
- package/dist/chunk-PUVEPQQ3.cjs +1805 -0
- package/dist/chunk-PUVEPQQ3.cjs.map +1 -0
- package/dist/chunk-R6JK3DE3.cjs +148 -0
- package/dist/chunk-R6JK3DE3.cjs.map +1 -0
- package/dist/chunk-Y3HWP75B.cjs +11974 -0
- package/dist/chunk-Y3HWP75B.cjs.map +1 -0
- package/dist/chunk-Y5PO67TG.cjs +2659 -0
- package/dist/chunk-Y5PO67TG.cjs.map +1 -0
- package/dist/cli.cjs +372 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +370 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +16 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +165 -0
- package/dist/index.d.ts +165 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/permissions-NRD36MYI.cjs +40 -0
- package/dist/permissions-NRD36MYI.cjs.map +1 -0
- package/dist/permissions-RC7CYR5H.js +3 -0
- package/dist/permissions-RC7CYR5H.js.map +1 -0
- package/dist/project-q9WpahUs.d.cts +329 -0
- package/dist/project-q9WpahUs.d.ts +329 -0
- package/dist/storage-6P53PQBL.cjs +24 -0
- package/dist/storage-6P53PQBL.cjs.map +1 -0
- package/dist/storage-QELMNBZ2.js +3 -0
- package/dist/storage-QELMNBZ2.js.map +1 -0
- package/dist/tui.cjs +76 -0
- package/dist/tui.cjs.map +1 -0
- package/dist/tui.d.cts +1013 -0
- package/dist/tui.d.ts +1013 -0
- package/dist/tui.js +3 -0
- package/dist/tui.js.map +1 -0
- package/package.json +107 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { WORKSPACE_TOOLS } from '@mastra/core/workspace';
|
|
2
|
+
|
|
3
|
+
// src/tool-names.ts
|
|
4
|
+
var MC_TOOLS = {
|
|
5
|
+
// Filesystem
|
|
6
|
+
VIEW: "view",
|
|
7
|
+
WRITE_FILE: "write_file",
|
|
8
|
+
STRING_REPLACE_LSP: "string_replace_lsp",
|
|
9
|
+
FIND_FILES: "find_files",
|
|
10
|
+
DELETE_FILE: "delete_file",
|
|
11
|
+
FILE_STAT: "file_stat",
|
|
12
|
+
MKDIR: "mkdir",
|
|
13
|
+
// Search
|
|
14
|
+
SEARCH_CONTENT: "search_content",
|
|
15
|
+
// Code intelligence
|
|
16
|
+
AST_SMART_EDIT: "ast_smart_edit",
|
|
17
|
+
// Sandbox
|
|
18
|
+
EXECUTE_COMMAND: "execute_command",
|
|
19
|
+
GET_PROCESS_OUTPUT: "get_process_output",
|
|
20
|
+
KILL_PROCESS: "kill_process"
|
|
21
|
+
};
|
|
22
|
+
var TOOL_NAME_OVERRIDES = {
|
|
23
|
+
[WORKSPACE_TOOLS.FILESYSTEM.READ_FILE]: { name: MC_TOOLS.VIEW },
|
|
24
|
+
[WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE]: { name: MC_TOOLS.WRITE_FILE },
|
|
25
|
+
[WORKSPACE_TOOLS.FILESYSTEM.EDIT_FILE]: { name: MC_TOOLS.STRING_REPLACE_LSP },
|
|
26
|
+
[WORKSPACE_TOOLS.FILESYSTEM.LIST_FILES]: { name: MC_TOOLS.FIND_FILES },
|
|
27
|
+
[WORKSPACE_TOOLS.FILESYSTEM.DELETE]: { name: MC_TOOLS.DELETE_FILE },
|
|
28
|
+
[WORKSPACE_TOOLS.FILESYSTEM.FILE_STAT]: { name: MC_TOOLS.FILE_STAT },
|
|
29
|
+
[WORKSPACE_TOOLS.FILESYSTEM.MKDIR]: { name: MC_TOOLS.MKDIR },
|
|
30
|
+
[WORKSPACE_TOOLS.FILESYSTEM.GREP]: { name: MC_TOOLS.SEARCH_CONTENT },
|
|
31
|
+
[WORKSPACE_TOOLS.FILESYSTEM.AST_EDIT]: { name: MC_TOOLS.AST_SMART_EDIT },
|
|
32
|
+
[WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: { name: MC_TOOLS.EXECUTE_COMMAND },
|
|
33
|
+
[WORKSPACE_TOOLS.SANDBOX.GET_PROCESS_OUTPUT]: { name: MC_TOOLS.GET_PROCESS_OUTPUT },
|
|
34
|
+
[WORKSPACE_TOOLS.SANDBOX.KILL_PROCESS]: { name: MC_TOOLS.KILL_PROCESS }
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// src/permissions.ts
|
|
38
|
+
var TOOL_CATEGORIES = {
|
|
39
|
+
read: {
|
|
40
|
+
label: "Read",
|
|
41
|
+
description: "Read files, search, list directories"
|
|
42
|
+
},
|
|
43
|
+
edit: {
|
|
44
|
+
label: "Edit",
|
|
45
|
+
description: "Create, modify, or delete files"
|
|
46
|
+
},
|
|
47
|
+
execute: {
|
|
48
|
+
label: "Execute",
|
|
49
|
+
description: "Run shell commands"
|
|
50
|
+
},
|
|
51
|
+
mcp: {
|
|
52
|
+
label: "MCP",
|
|
53
|
+
description: "External MCP server tools"
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var TOOL_CATEGORY_MAP = {
|
|
57
|
+
// Read-only tools — always safe
|
|
58
|
+
[MC_TOOLS.VIEW]: "read",
|
|
59
|
+
[MC_TOOLS.SEARCH_CONTENT]: "read",
|
|
60
|
+
[MC_TOOLS.FIND_FILES]: "read",
|
|
61
|
+
web_search: "read",
|
|
62
|
+
"web-search": "read",
|
|
63
|
+
web_extract: "read",
|
|
64
|
+
"web-extract": "read",
|
|
65
|
+
// Edit tools — modify files
|
|
66
|
+
[MC_TOOLS.STRING_REPLACE_LSP]: "edit",
|
|
67
|
+
[MC_TOOLS.AST_SMART_EDIT]: "edit",
|
|
68
|
+
[MC_TOOLS.WRITE_FILE]: "edit",
|
|
69
|
+
subagent: "edit",
|
|
70
|
+
// Execute tools — run arbitrary commands
|
|
71
|
+
[MC_TOOLS.EXECUTE_COMMAND]: "execute"
|
|
72
|
+
// Interactive / planning tools — always allowed (no category needed)
|
|
73
|
+
// ask_user, task_write, task_check, submit_plan, request_access
|
|
74
|
+
};
|
|
75
|
+
var ALWAYS_ALLOW_TOOLS = /* @__PURE__ */ new Set(["ask_user", "task_write", "task_check", "submit_plan", "request_access"]);
|
|
76
|
+
function getToolCategory(toolName) {
|
|
77
|
+
if (ALWAYS_ALLOW_TOOLS.has(toolName)) return null;
|
|
78
|
+
return TOOL_CATEGORY_MAP[toolName] ?? "mcp";
|
|
79
|
+
}
|
|
80
|
+
function getToolsForCategory(category) {
|
|
81
|
+
return Object.entries(TOOL_CATEGORY_MAP).filter(([, cat]) => cat === category).map(([tool]) => tool);
|
|
82
|
+
}
|
|
83
|
+
var DEFAULT_POLICIES = {
|
|
84
|
+
read: "allow",
|
|
85
|
+
edit: "ask",
|
|
86
|
+
execute: "ask",
|
|
87
|
+
mcp: "ask"
|
|
88
|
+
};
|
|
89
|
+
var YOLO_POLICIES = {
|
|
90
|
+
read: "allow",
|
|
91
|
+
edit: "allow",
|
|
92
|
+
execute: "allow",
|
|
93
|
+
mcp: "allow"
|
|
94
|
+
};
|
|
95
|
+
function createDefaultRules() {
|
|
96
|
+
return {
|
|
97
|
+
categories: { ...DEFAULT_POLICIES },
|
|
98
|
+
tools: {}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
var SessionGrants = class {
|
|
102
|
+
grantedCategories = /* @__PURE__ */ new Set();
|
|
103
|
+
grantedTools = /* @__PURE__ */ new Set();
|
|
104
|
+
allowCategory(category) {
|
|
105
|
+
this.grantedCategories.add(category);
|
|
106
|
+
}
|
|
107
|
+
allowTool(toolName) {
|
|
108
|
+
this.grantedTools.add(toolName);
|
|
109
|
+
}
|
|
110
|
+
isGranted(toolName, category) {
|
|
111
|
+
return this.grantedTools.has(toolName) || this.grantedCategories.has(category);
|
|
112
|
+
}
|
|
113
|
+
reset() {
|
|
114
|
+
this.grantedCategories.clear();
|
|
115
|
+
this.grantedTools.clear();
|
|
116
|
+
}
|
|
117
|
+
getGrantedCategories() {
|
|
118
|
+
return [...this.grantedCategories];
|
|
119
|
+
}
|
|
120
|
+
getGrantedTools() {
|
|
121
|
+
return [...this.grantedTools];
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
function resolveApproval(toolName, rules, sessionGrants) {
|
|
125
|
+
const category = getToolCategory(toolName);
|
|
126
|
+
if (category === null) return "allow";
|
|
127
|
+
const toolPolicy = rules.tools[toolName];
|
|
128
|
+
if (toolPolicy) return toolPolicy;
|
|
129
|
+
if (sessionGrants.isGranted(toolName, category)) return "allow";
|
|
130
|
+
const categoryPolicy = rules.categories[category];
|
|
131
|
+
if (categoryPolicy) return categoryPolicy;
|
|
132
|
+
return DEFAULT_POLICIES[category] ?? "ask";
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export { DEFAULT_POLICIES, MC_TOOLS, SessionGrants, TOOL_CATEGORIES, TOOL_NAME_OVERRIDES, YOLO_POLICIES, createDefaultRules, getToolCategory, getToolsForCategory, resolveApproval };
|
|
136
|
+
//# sourceMappingURL=chunk-MS5RYNRK.js.map
|
|
137
|
+
//# sourceMappingURL=chunk-MS5RYNRK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tool-names.ts","../src/permissions.ts"],"names":[],"mappings":"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","file":"chunk-MS5RYNRK.js","sourcesContent":["/**\n * Mastracode tool name constants.\n *\n * These are the names exposed to the LLM via workspace tool name remapping.\n * Used throughout mastracode for permissions, TUI rendering, tool guidance,\n * subagent allowedTools, etc.\n *\n * The workspace tools get remapped from their core names (e.g. `mastra_workspace_read_file`)\n * to these names (e.g. `view`) via the `name` property in workspace tool config.\n */\n\nimport { WORKSPACE_TOOLS } from '@mastra/core/workspace';\n\nexport const MC_TOOLS = {\n // Filesystem\n VIEW: 'view',\n WRITE_FILE: 'write_file',\n STRING_REPLACE_LSP: 'string_replace_lsp',\n FIND_FILES: 'find_files',\n DELETE_FILE: 'delete_file',\n FILE_STAT: 'file_stat',\n MKDIR: 'mkdir',\n\n // Search\n SEARCH_CONTENT: 'search_content',\n\n // Code intelligence\n AST_SMART_EDIT: 'ast_smart_edit',\n\n // Sandbox\n EXECUTE_COMMAND: 'execute_command',\n GET_PROCESS_OUTPUT: 'get_process_output',\n KILL_PROCESS: 'kill_process',\n} as const;\n\n/**\n * Workspace tool name remapping config.\n * Maps core workspace tool constants to mastracode's tool names.\n * Pass this (or spread it) into `Workspace({ tools: ... })`.\n */\nexport const TOOL_NAME_OVERRIDES = {\n [WORKSPACE_TOOLS.FILESYSTEM.READ_FILE]: { name: MC_TOOLS.VIEW },\n [WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE]: { name: MC_TOOLS.WRITE_FILE },\n [WORKSPACE_TOOLS.FILESYSTEM.EDIT_FILE]: { name: MC_TOOLS.STRING_REPLACE_LSP },\n [WORKSPACE_TOOLS.FILESYSTEM.LIST_FILES]: { name: MC_TOOLS.FIND_FILES },\n [WORKSPACE_TOOLS.FILESYSTEM.DELETE]: { name: MC_TOOLS.DELETE_FILE },\n [WORKSPACE_TOOLS.FILESYSTEM.FILE_STAT]: { name: MC_TOOLS.FILE_STAT },\n [WORKSPACE_TOOLS.FILESYSTEM.MKDIR]: { name: MC_TOOLS.MKDIR },\n [WORKSPACE_TOOLS.FILESYSTEM.GREP]: { name: MC_TOOLS.SEARCH_CONTENT },\n [WORKSPACE_TOOLS.FILESYSTEM.AST_EDIT]: { name: MC_TOOLS.AST_SMART_EDIT },\n [WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: { name: MC_TOOLS.EXECUTE_COMMAND },\n [WORKSPACE_TOOLS.SANDBOX.GET_PROCESS_OUTPUT]: { name: MC_TOOLS.GET_PROCESS_OUTPUT },\n [WORKSPACE_TOOLS.SANDBOX.KILL_PROCESS]: { name: MC_TOOLS.KILL_PROCESS },\n} as const;\n","/**\n * Granular tool permission system.\n *\n * Tools are classified into categories by risk level.\n * Each category has a configurable policy: \"allow\", \"ask\", or \"deny\".\n * Session-scoped grants let the user approve a category once per session.\n */\n\nimport { MC_TOOLS } from './tool-names.js';\n\n// ---------------------------------------------------------------------------\n// Categories\n// ---------------------------------------------------------------------------\n\nexport type ToolCategory = 'read' | 'edit' | 'execute' | 'mcp';\n\nexport const TOOL_CATEGORIES: Record<ToolCategory, { label: string; description: string }> = {\n read: {\n label: 'Read',\n description: 'Read files, search, list directories',\n },\n edit: {\n label: 'Edit',\n description: 'Create, modify, or delete files',\n },\n execute: {\n label: 'Execute',\n description: 'Run shell commands',\n },\n mcp: {\n label: 'MCP',\n description: 'External MCP server tools',\n },\n};\n\n// ---------------------------------------------------------------------------\n// Tool → Category mapping\n// ---------------------------------------------------------------------------\n\nconst TOOL_CATEGORY_MAP: Record<string, ToolCategory> = {\n // Read-only tools — always safe\n [MC_TOOLS.VIEW]: 'read',\n [MC_TOOLS.SEARCH_CONTENT]: 'read',\n [MC_TOOLS.FIND_FILES]: 'read',\n web_search: 'read',\n 'web-search': 'read',\n web_extract: 'read',\n 'web-extract': 'read',\n // Edit tools — modify files\n [MC_TOOLS.STRING_REPLACE_LSP]: 'edit',\n [MC_TOOLS.AST_SMART_EDIT]: 'edit',\n [MC_TOOLS.WRITE_FILE]: 'edit',\n subagent: 'edit',\n\n // Execute tools — run arbitrary commands\n [MC_TOOLS.EXECUTE_COMMAND]: 'execute',\n\n // Interactive / planning tools — always allowed (no category needed)\n // ask_user, task_write, task_check, submit_plan, request_access\n};\n\n// Tools that never need approval regardless of policy\nconst ALWAYS_ALLOW_TOOLS = new Set(['ask_user', 'task_write', 'task_check', 'submit_plan', 'request_access']);\n\n/**\n * Get the category for a tool, or null if the tool is always-allowed.\n */\nexport function getToolCategory(toolName: string): ToolCategory | null {\n if (ALWAYS_ALLOW_TOOLS.has(toolName)) return null;\n return TOOL_CATEGORY_MAP[toolName] ?? 'mcp';\n}\n\n/**\n * Get the list of known tools for a given category.\n */\nexport function getToolsForCategory(category: ToolCategory): string[] {\n return Object.entries(TOOL_CATEGORY_MAP)\n .filter(([, cat]) => cat === category)\n .map(([tool]) => tool);\n}\n\n// ---------------------------------------------------------------------------\n// Policies\n// ---------------------------------------------------------------------------\n\nexport type PermissionPolicy = 'allow' | 'ask' | 'deny';\n\nexport interface PermissionRules {\n /** Policy per category. Missing categories default to their DEFAULT_POLICIES value. */\n categories: Partial<Record<ToolCategory, PermissionPolicy>>;\n /** Per-tool overrides. Tool name → policy. Takes precedence over category. */\n tools: Record<string, PermissionPolicy>;\n}\n\n/** Default policies when no rules are configured (YOLO=false equivalent). */\nexport const DEFAULT_POLICIES: Record<ToolCategory, PermissionPolicy> = {\n read: 'allow',\n edit: 'ask',\n execute: 'ask',\n mcp: 'ask',\n};\n\n/** YOLO-mode policies — everything auto-allowed. */\nexport const YOLO_POLICIES: Record<ToolCategory, PermissionPolicy> = {\n read: 'allow',\n edit: 'allow',\n execute: 'allow',\n mcp: 'allow',\n};\n\nexport function createDefaultRules(): PermissionRules {\n return {\n categories: { ...DEFAULT_POLICIES },\n tools: {},\n };\n}\n\n// ---------------------------------------------------------------------------\n// Session grants — temporary \"always allow\" for this session\n// ---------------------------------------------------------------------------\n\nexport class SessionGrants {\n private grantedCategories = new Set<ToolCategory>();\n private grantedTools = new Set<string>();\n\n allowCategory(category: ToolCategory): void {\n this.grantedCategories.add(category);\n }\n\n allowTool(toolName: string): void {\n this.grantedTools.add(toolName);\n }\n\n isGranted(toolName: string, category: ToolCategory): boolean {\n return this.grantedTools.has(toolName) || this.grantedCategories.has(category);\n }\n\n reset(): void {\n this.grantedCategories.clear();\n this.grantedTools.clear();\n }\n\n getGrantedCategories(): ToolCategory[] {\n return [...this.grantedCategories];\n }\n\n getGrantedTools(): string[] {\n return [...this.grantedTools];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Decision engine\n// ---------------------------------------------------------------------------\n\nexport type ApprovalDecision = 'allow' | 'ask' | 'deny';\n\n/**\n * Determine whether a tool call should be allowed, prompted, or denied.\n *\n * Priority order:\n * 1. Always-allowed tools (ask_user, task_write, etc.) → allow\n * 2. Per-tool policy override → use that policy\n * 3. Session grants (user said \"always allow\" during this session) → allow\n * 4. Category policy → use that policy\n * 5. Fallback → \"ask\"\n */\nexport function resolveApproval(\n toolName: string,\n rules: PermissionRules,\n sessionGrants: SessionGrants,\n): ApprovalDecision {\n // 1. Always-allowed tools\n const category = getToolCategory(toolName);\n if (category === null) return 'allow';\n\n // 2. Per-tool override\n const toolPolicy = rules.tools[toolName];\n if (toolPolicy) return toolPolicy;\n\n // 3. Session grants\n if (sessionGrants.isGranted(toolName, category)) return 'allow';\n\n // 4. Category policy\n const categoryPolicy = rules.categories[category];\n if (categoryPolicy) return categoryPolicy;\n\n // 5. Default policy for category\n return DEFAULT_POLICIES[category] ?? 'ask';\n}\n"]}
|