zora-agent 0.9.4 → 0.9.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 +1 -1
- package/README.md +103 -92
- package/dist/cli/audit-commands.d.ts.map +1 -1
- package/dist/cli/audit-commands.js +3 -1
- package/dist/cli/audit-commands.js.map +1 -1
- package/dist/cli/daemon.js +86 -28
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/edit-commands.d.ts.map +1 -1
- package/dist/cli/edit-commands.js +3 -1
- package/dist/cli/edit-commands.js.map +1 -1
- package/dist/cli/hook-commands.d.ts +9 -0
- package/dist/cli/hook-commands.d.ts.map +1 -0
- package/dist/cli/hook-commands.js +106 -0
- package/dist/cli/hook-commands.js.map +1 -0
- package/dist/cli/index.js +87 -35
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init-command.d.ts.map +1 -1
- package/dist/cli/init-command.js +108 -9
- package/dist/cli/init-command.js.map +1 -1
- package/dist/cli/memory-commands.d.ts +1 -1
- package/dist/cli/memory-commands.d.ts.map +1 -1
- package/dist/cli/memory-commands.js +213 -1
- package/dist/cli/memory-commands.js.map +1 -1
- package/dist/cli/presets.d.ts.map +1 -1
- package/dist/cli/presets.js +2 -1
- package/dist/cli/presets.js.map +1 -1
- package/dist/cli/skill-commands.d.ts.map +1 -1
- package/dist/cli/skill-commands.js +4 -2
- package/dist/cli/skill-commands.js.map +1 -1
- package/dist/cli/steer-commands.d.ts.map +1 -1
- package/dist/cli/steer-commands.js +6 -4
- package/dist/cli/steer-commands.js.map +1 -1
- package/dist/cli/team-commands.d.ts.map +1 -1
- package/dist/cli/team-commands.js +3 -1
- package/dist/cli/team-commands.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +12 -2
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/loader.d.ts +23 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +64 -3
- package/dist/config/loader.js.map +1 -1
- package/dist/config/policy-loader.d.ts +14 -0
- package/dist/config/policy-loader.d.ts.map +1 -1
- package/dist/config/policy-loader.js +33 -0
- package/dist/config/policy-loader.js.map +1 -1
- package/dist/dashboard/frontend/dist/assets/index-BcOGj1EF.css +1 -0
- package/dist/dashboard/frontend/dist/assets/index-BtiFO9YN.js +261 -0
- package/dist/dashboard/frontend/dist/assets/index-Cfjy5acU.css +1 -0
- package/dist/dashboard/frontend/dist/assets/index-D41hcjgc.js +253 -0
- package/dist/dashboard/frontend/dist/assets/index-D83BawFd.css +1 -0
- package/dist/dashboard/frontend/dist/assets/index-DAODjoxu.css +1 -0
- package/dist/dashboard/frontend/dist/assets/index-DB-Eu5oV.js +253 -0
- package/dist/dashboard/frontend/dist/assets/index-W0VVEDu6.js +253 -0
- package/dist/dashboard/frontend/dist/index.html +17 -0
- package/dist/dashboard/server.d.ts +19 -2
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +121 -20
- package/dist/dashboard/server.js.map +1 -1
- package/dist/hooks/hook-runner.d.ts +55 -0
- package/dist/hooks/hook-runner.d.ts.map +1 -0
- package/dist/hooks/hook-runner.js +120 -0
- package/dist/hooks/hook-runner.js.map +1 -0
- package/dist/hooks/hook-types.d.ts +82 -0
- package/dist/hooks/hook-types.d.ts.map +1 -0
- package/dist/hooks/hook-types.js +20 -0
- package/dist/hooks/hook-types.js.map +1 -0
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +6 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/memory/context-compressor.d.ts +108 -0
- package/dist/memory/context-compressor.d.ts.map +1 -0
- package/dist/memory/context-compressor.js +307 -0
- package/dist/memory/context-compressor.js.map +1 -0
- package/dist/memory/index.d.ts +1 -0
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +1 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/memory-manager.d.ts +88 -4
- package/dist/memory/memory-manager.d.ts.map +1 -1
- package/dist/memory/memory-manager.js +299 -7
- package/dist/memory/memory-manager.js.map +1 -1
- package/dist/memory/observation-store.d.ts +75 -0
- package/dist/memory/observation-store.d.ts.map +1 -0
- package/dist/memory/observation-store.js +162 -0
- package/dist/memory/observation-store.js.map +1 -0
- package/dist/memory/observer-worker.d.ts +34 -0
- package/dist/memory/observer-worker.d.ts.map +1 -0
- package/dist/memory/observer-worker.js +161 -0
- package/dist/memory/observer-worker.js.map +1 -0
- package/dist/memory/reflector-worker.d.ts +40 -0
- package/dist/memory/reflector-worker.d.ts.map +1 -0
- package/dist/memory/reflector-worker.js +185 -0
- package/dist/memory/reflector-worker.js.map +1 -0
- package/dist/memory/salience-scorer.d.ts +16 -6
- package/dist/memory/salience-scorer.d.ts.map +1 -1
- package/dist/memory/salience-scorer.js +42 -22
- package/dist/memory/salience-scorer.js.map +1 -1
- package/dist/memory/structured-memory.d.ts +36 -1
- package/dist/memory/structured-memory.d.ts.map +1 -1
- package/dist/memory/structured-memory.js +207 -8
- package/dist/memory/structured-memory.js.map +1 -1
- package/dist/memory/token-estimator.d.ts +31 -0
- package/dist/memory/token-estimator.d.ts.map +1 -0
- package/dist/memory/token-estimator.js +77 -0
- package/dist/memory/token-estimator.js.map +1 -0
- package/dist/memory/validation-pipeline.d.ts +37 -0
- package/dist/memory/validation-pipeline.d.ts.map +1 -0
- package/dist/memory/validation-pipeline.js +106 -0
- package/dist/memory/validation-pipeline.js.map +1 -0
- package/dist/orchestrator/auth-monitor.d.ts.map +1 -1
- package/dist/orchestrator/auth-monitor.js +3 -1
- package/dist/orchestrator/auth-monitor.js.map +1 -1
- package/dist/orchestrator/execution-loop.d.ts +23 -0
- package/dist/orchestrator/execution-loop.d.ts.map +1 -1
- package/dist/orchestrator/execution-loop.js +60 -19
- package/dist/orchestrator/execution-loop.js.map +1 -1
- package/dist/orchestrator/failover-controller.d.ts +26 -2
- package/dist/orchestrator/failover-controller.d.ts.map +1 -1
- package/dist/orchestrator/failover-controller.js +143 -23
- package/dist/orchestrator/failover-controller.js.map +1 -1
- package/dist/orchestrator/orchestrator.d.ts +70 -7
- package/dist/orchestrator/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/orchestrator.js +416 -92
- package/dist/orchestrator/orchestrator.js.map +1 -1
- package/dist/orchestrator/retry-queue.d.ts.map +1 -1
- package/dist/orchestrator/retry-queue.js +24 -9
- package/dist/orchestrator/retry-queue.js.map +1 -1
- package/dist/orchestrator/router.d.ts +16 -1
- package/dist/orchestrator/router.d.ts.map +1 -1
- package/dist/orchestrator/router.js +79 -20
- package/dist/orchestrator/router.js.map +1 -1
- package/dist/orchestrator/session-manager.d.ts +26 -1
- package/dist/orchestrator/session-manager.d.ts.map +1 -1
- package/dist/orchestrator/session-manager.js +88 -4
- package/dist/orchestrator/session-manager.js.map +1 -1
- package/dist/providers/circuit-breaker.d.ts +78 -0
- package/dist/providers/circuit-breaker.d.ts.map +1 -0
- package/dist/providers/circuit-breaker.js +129 -0
- package/dist/providers/circuit-breaker.js.map +1 -0
- package/dist/providers/claude-provider.d.ts +27 -11
- package/dist/providers/claude-provider.d.ts.map +1 -1
- package/dist/providers/claude-provider.js +161 -46
- package/dist/providers/claude-provider.js.map +1 -1
- package/dist/providers/gemini-provider.d.ts +9 -1
- package/dist/providers/gemini-provider.d.ts.map +1 -1
- package/dist/providers/gemini-provider.js +97 -48
- package/dist/providers/gemini-provider.js.map +1 -1
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +1 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/ollama-provider.d.ts +7 -0
- package/dist/providers/ollama-provider.d.ts.map +1 -1
- package/dist/providers/ollama-provider.js +89 -18
- package/dist/providers/ollama-provider.js.map +1 -1
- package/dist/routines/heartbeat.d.ts +10 -2
- package/dist/routines/heartbeat.d.ts.map +1 -1
- package/dist/routines/heartbeat.js +42 -5
- package/dist/routines/heartbeat.js.map +1 -1
- package/dist/routines/routine-manager.d.ts.map +1 -1
- package/dist/routines/routine-manager.js +22 -15
- package/dist/routines/routine-manager.js.map +1 -1
- package/dist/security/audit-logger.d.ts.map +1 -1
- package/dist/security/audit-logger.js +5 -7
- package/dist/security/audit-logger.js.map +1 -1
- package/dist/security/policy-engine.d.ts +28 -17
- package/dist/security/policy-engine.d.ts.map +1 -1
- package/dist/security/policy-engine.js +42 -185
- package/dist/security/policy-engine.js.map +1 -1
- package/dist/security/policy-serializer.d.ts +19 -0
- package/dist/security/policy-serializer.d.ts.map +1 -0
- package/dist/security/policy-serializer.js +100 -0
- package/dist/security/policy-serializer.js.map +1 -0
- package/dist/security/shell-validator.d.ts +42 -0
- package/dist/security/shell-validator.d.ts.map +1 -0
- package/dist/security/shell-validator.js +231 -0
- package/dist/security/shell-validator.js.map +1 -0
- package/dist/skills/index.d.ts +1 -0
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +1 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/skill-loader.d.ts +38 -2
- package/dist/skills/skill-loader.d.ts.map +1 -1
- package/dist/skills/skill-loader.js +83 -2
- package/dist/skills/skill-loader.js.map +1 -1
- package/dist/skills/subagent-loader.d.ts +66 -0
- package/dist/skills/subagent-loader.d.ts.map +1 -0
- package/dist/skills/subagent-loader.js +143 -0
- package/dist/skills/subagent-loader.js.map +1 -0
- package/dist/steering/flag-manager.d.ts +20 -0
- package/dist/steering/flag-manager.d.ts.map +1 -1
- package/dist/steering/flag-manager.js +94 -11
- package/dist/steering/flag-manager.js.map +1 -1
- package/dist/steering/steering-manager.d.ts +11 -0
- package/dist/steering/steering-manager.d.ts.map +1 -1
- package/dist/steering/steering-manager.js +23 -0
- package/dist/steering/steering-manager.js.map +1 -1
- package/dist/steering/telegram-gateway.d.ts +4 -1
- package/dist/steering/telegram-gateway.d.ts.map +1 -1
- package/dist/steering/telegram-gateway.js +49 -10
- package/dist/steering/telegram-gateway.js.map +1 -1
- package/dist/teams/bridge-watchdog.d.ts.map +1 -1
- package/dist/teams/bridge-watchdog.js +5 -3
- package/dist/teams/bridge-watchdog.js.map +1 -1
- package/dist/teams/gemini-bridge.d.ts.map +1 -1
- package/dist/teams/gemini-bridge.js +9 -4
- package/dist/teams/gemini-bridge.js.map +1 -1
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/memory-tools.d.ts +16 -0
- package/dist/tools/memory-tools.d.ts.map +1 -0
- package/dist/tools/memory-tools.js +207 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/tools/notifications.d.ts.map +1 -1
- package/dist/tools/notifications.js +3 -1
- package/dist/tools/notifications.js.map +1 -1
- package/dist/tools/tool-factory.d.ts +36 -0
- package/dist/tools/tool-factory.d.ts.map +1 -0
- package/dist/tools/tool-factory.js +55 -0
- package/dist/tools/tool-factory.js.map +1 -0
- package/dist/types.d.ts +205 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +47 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/errors.d.ts +21 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +29 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/event-filter.d.ts +25 -0
- package/dist/utils/event-filter.d.ts.map +1 -0
- package/dist/utils/event-filter.js +61 -0
- package/dist/utils/event-filter.js.map +1 -0
- package/dist/utils/logger.d.ts +33 -36
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +60 -130
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/validate-job-id.d.ts +6 -0
- package/dist/utils/validate-job-id.d.ts.map +1 -0
- package/dist/utils/validate-job-id.js +10 -0
- package/dist/utils/validate-job-id.js.map +1 -0
- package/package.json +12 -3
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy serialization and summary utilities.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from PolicyEngine to separate concerns:
|
|
5
|
+
* - Human-readable policy summaries (for system prompt injection)
|
|
6
|
+
* - TOML file serialization (for runtime policy persistence)
|
|
7
|
+
*/
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import { createLogger } from '../utils/logger.js';
|
|
10
|
+
const log = createLogger('policy-serializer');
|
|
11
|
+
/**
|
|
12
|
+
* Returns a short text summary of the current policy for system prompt injection.
|
|
13
|
+
* Intentionally terse to minimize context usage.
|
|
14
|
+
*/
|
|
15
|
+
export function getPolicySummary(policy) {
|
|
16
|
+
const fsPolicy = policy.filesystem;
|
|
17
|
+
const sh = policy.shell;
|
|
18
|
+
const lines = [];
|
|
19
|
+
if (fsPolicy.allowed_paths.length === 0) {
|
|
20
|
+
lines.push('Filesystem: LOCKED (no paths allowed)');
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
lines.push(`Filesystem: ${fsPolicy.allowed_paths.join(', ')}`);
|
|
24
|
+
}
|
|
25
|
+
if (fsPolicy.denied_paths.length > 0) {
|
|
26
|
+
lines.push(`Denied: ${fsPolicy.denied_paths.join(', ')}`);
|
|
27
|
+
}
|
|
28
|
+
if (sh.mode === 'deny_all') {
|
|
29
|
+
lines.push('Shell: DISABLED (no commands allowed)');
|
|
30
|
+
}
|
|
31
|
+
else if (sh.mode === 'allowlist') {
|
|
32
|
+
lines.push(`Shell: ${sh.allowed_commands.join(', ')}`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
lines.push('Shell: denylist mode');
|
|
36
|
+
}
|
|
37
|
+
if (policy.budget) {
|
|
38
|
+
const b = policy.budget;
|
|
39
|
+
lines.push(`Budget: ${b.max_actions_per_session || 'unlimited'} actions/session, ${b.token_budget || 'unlimited'} tokens`);
|
|
40
|
+
}
|
|
41
|
+
if (policy.dry_run?.enabled) {
|
|
42
|
+
lines.push('Dry Run: ENABLED (write operations will be previewed only)');
|
|
43
|
+
}
|
|
44
|
+
return lines.join('\n');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Writes the policy state to a TOML file.
|
|
48
|
+
* Builds TOML manually for simplicity (avoids needing smol-toml at runtime).
|
|
49
|
+
*/
|
|
50
|
+
export function writePolicyFile(policy, filePath) {
|
|
51
|
+
try {
|
|
52
|
+
// Build TOML manually for simplicity (avoids needing smol-toml at runtime here)
|
|
53
|
+
const lines = [
|
|
54
|
+
'# Zora Security Policy — auto-generated (runtime expansion applied)',
|
|
55
|
+
'',
|
|
56
|
+
'[filesystem]',
|
|
57
|
+
`allowed_paths = ${JSON.stringify(policy.filesystem.allowed_paths)}`,
|
|
58
|
+
`denied_paths = ${JSON.stringify(policy.filesystem.denied_paths)}`,
|
|
59
|
+
`resolve_symlinks = ${policy.filesystem.resolve_symlinks}`,
|
|
60
|
+
`follow_symlinks = ${policy.filesystem.follow_symlinks}`,
|
|
61
|
+
'',
|
|
62
|
+
'[shell]',
|
|
63
|
+
`mode = "${policy.shell.mode}"`,
|
|
64
|
+
`allowed_commands = ${JSON.stringify(policy.shell.allowed_commands)}`,
|
|
65
|
+
`denied_commands = ${JSON.stringify(policy.shell.denied_commands)}`,
|
|
66
|
+
`split_chained_commands = ${policy.shell.split_chained_commands}`,
|
|
67
|
+
`max_execution_time = "${policy.shell.max_execution_time}"`,
|
|
68
|
+
'',
|
|
69
|
+
'[actions]',
|
|
70
|
+
`reversible = ${JSON.stringify(policy.actions.reversible)}`,
|
|
71
|
+
`irreversible = ${JSON.stringify(policy.actions.irreversible)}`,
|
|
72
|
+
`always_flag = ${JSON.stringify(policy.actions.always_flag)}`,
|
|
73
|
+
'',
|
|
74
|
+
'[network]',
|
|
75
|
+
`allowed_domains = ${JSON.stringify(policy.network.allowed_domains)}`,
|
|
76
|
+
`denied_domains = ${JSON.stringify(policy.network.denied_domains)}`,
|
|
77
|
+
`max_request_size = "${policy.network.max_request_size}"`,
|
|
78
|
+
'',
|
|
79
|
+
];
|
|
80
|
+
// Serialize budget section if present
|
|
81
|
+
if (policy.budget) {
|
|
82
|
+
const b = policy.budget;
|
|
83
|
+
lines.push('[budget]', `max_actions_per_session = ${b.max_actions_per_session}`, `token_budget = ${b.token_budget}`, `on_exceed = "${b.on_exceed}"`, '', '[budget.max_actions_per_type]');
|
|
84
|
+
for (const [type, limit] of Object.entries(b.max_actions_per_type)) {
|
|
85
|
+
lines.push(`${type} = ${limit}`);
|
|
86
|
+
}
|
|
87
|
+
lines.push('');
|
|
88
|
+
}
|
|
89
|
+
// Serialize dry_run section if present
|
|
90
|
+
if (policy.dry_run) {
|
|
91
|
+
const dr = policy.dry_run;
|
|
92
|
+
lines.push('[dry_run]', `enabled = ${dr.enabled}`, `tools = ${JSON.stringify(dr.tools)}`, `audit_dry_runs = ${dr.audit_dry_runs}`, '');
|
|
93
|
+
}
|
|
94
|
+
fs.writeFileSync(filePath, lines.join('\n'), 'utf-8');
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
log.error({ err: err instanceof Error ? err.message : String(err) }, 'Failed to persist policy expansion');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=policy-serializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-serializer.js","sourceRoot":"","sources":["../../src/security/policy-serializer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell command parsing and validation utilities.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions extracted from PolicyEngine for shell tokenization,
|
|
5
|
+
* command splitting, base command extraction, and read-only detection.
|
|
6
|
+
*
|
|
7
|
+
* These are stateless string parsers with no class dependencies.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Tokenize a shell command string into individual arguments.
|
|
11
|
+
*
|
|
12
|
+
* Handles POSIX shell quoting rules:
|
|
13
|
+
* - Double quotes: interprets \\", \\\\, \\$, \\` as escape sequences.
|
|
14
|
+
* - Single quotes: all characters are literal (no escape sequences).
|
|
15
|
+
* - Backslash outside quotes: next character is taken literally.
|
|
16
|
+
* - Whitespace outside quotes: terminates the current token.
|
|
17
|
+
*
|
|
18
|
+
* Returns unquoted token values (quotes and escapes are resolved).
|
|
19
|
+
* Used by validateCommand to extract the base command name, and by
|
|
20
|
+
* _checkCommandPaths to find path-like arguments.
|
|
21
|
+
*/
|
|
22
|
+
export declare function shellTokenize(input: string): string[];
|
|
23
|
+
/**
|
|
24
|
+
* Splits command chains on operators (&&, ||, ;, |) while respecting:
|
|
25
|
+
* - Quoted strings (single and double) -- operators inside quotes are literal.
|
|
26
|
+
* - Escape sequences -- backslash-escaped characters are not treated as operators.
|
|
27
|
+
* - Command substitution -- $(...) and backtick blocks are treated as opaque.
|
|
28
|
+
* Nested $() is tracked via parenDepth to avoid premature splitting.
|
|
29
|
+
*
|
|
30
|
+
* Each returned string is a standalone command to validate independently.
|
|
31
|
+
*/
|
|
32
|
+
export declare function splitChainedCommands(command: string): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Extracts the base binary name from a command string, respecting quotes
|
|
35
|
+
* and escape sequences.
|
|
36
|
+
*/
|
|
37
|
+
export declare function extractBaseCommand(command: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Determine if a bash command is read-only.
|
|
40
|
+
*/
|
|
41
|
+
export declare function isReadOnlyCommand(command: string): boolean;
|
|
42
|
+
//# sourceMappingURL=shell-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-validator.d.ts","sourceRoot":"","sources":["../../src/security/shell-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAYH;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAsErD;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAgG9D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAe1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAY1D"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell command parsing and validation utilities.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions extracted from PolicyEngine for shell tokenization,
|
|
5
|
+
* command splitting, base command extraction, and read-only detection.
|
|
6
|
+
*
|
|
7
|
+
* These are stateless string parsers with no class dependencies.
|
|
8
|
+
*/
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
/**
|
|
11
|
+
* Set of commands considered read-only (safe to execute even in dry-run).
|
|
12
|
+
*/
|
|
13
|
+
const READ_ONLY_COMMANDS = new Set([
|
|
14
|
+
'ls', 'cat', 'head', 'tail', 'grep', 'rg', 'find', 'which', 'pwd',
|
|
15
|
+
'wc', 'diff', 'file', 'stat', 'echo', 'env', 'printenv', 'date', 'whoami',
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Tokenize a shell command string into individual arguments.
|
|
19
|
+
*
|
|
20
|
+
* Handles POSIX shell quoting rules:
|
|
21
|
+
* - Double quotes: interprets \\", \\\\, \\$, \\` as escape sequences.
|
|
22
|
+
* - Single quotes: all characters are literal (no escape sequences).
|
|
23
|
+
* - Backslash outside quotes: next character is taken literally.
|
|
24
|
+
* - Whitespace outside quotes: terminates the current token.
|
|
25
|
+
*
|
|
26
|
+
* Returns unquoted token values (quotes and escapes are resolved).
|
|
27
|
+
* Used by validateCommand to extract the base command name, and by
|
|
28
|
+
* _checkCommandPaths to find path-like arguments.
|
|
29
|
+
*/
|
|
30
|
+
export function shellTokenize(input) {
|
|
31
|
+
const tokens = [];
|
|
32
|
+
let current = '';
|
|
33
|
+
let inToken = false;
|
|
34
|
+
let i = 0;
|
|
35
|
+
const finishToken = () => {
|
|
36
|
+
if (inToken) {
|
|
37
|
+
tokens.push(current);
|
|
38
|
+
current = '';
|
|
39
|
+
inToken = false;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
while (i < input.length) {
|
|
43
|
+
const ch = input[i];
|
|
44
|
+
// Whitespace outside quotes ends the current token
|
|
45
|
+
if (/\s/.test(ch)) {
|
|
46
|
+
finishToken();
|
|
47
|
+
i++;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
inToken = true;
|
|
51
|
+
if (ch === '\\' && i + 1 < input.length) {
|
|
52
|
+
// Backslash escape outside quotes: take next char literally
|
|
53
|
+
current += input[i + 1];
|
|
54
|
+
i += 2;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (ch === '"') {
|
|
58
|
+
// Double-quoted string: handle \", \\, \$, \`
|
|
59
|
+
i++; // skip opening "
|
|
60
|
+
while (i < input.length && input[i] !== '"') {
|
|
61
|
+
if (input[i] === '\\' && i + 1 < input.length) {
|
|
62
|
+
const next = input[i + 1];
|
|
63
|
+
if (next === '"' || next === '\\' || next === '$' || next === '`') {
|
|
64
|
+
current += next;
|
|
65
|
+
i += 2;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
current += input[i];
|
|
70
|
+
i++;
|
|
71
|
+
}
|
|
72
|
+
i++; // skip closing "
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (ch === "'") {
|
|
76
|
+
// Single-quoted string: everything is literal, no escape sequences
|
|
77
|
+
i++; // skip opening '
|
|
78
|
+
while (i < input.length && input[i] !== "'") {
|
|
79
|
+
current += input[i];
|
|
80
|
+
i++;
|
|
81
|
+
}
|
|
82
|
+
i++; // skip closing '
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
// Regular character
|
|
86
|
+
current += ch;
|
|
87
|
+
i++;
|
|
88
|
+
}
|
|
89
|
+
finishToken();
|
|
90
|
+
return tokens;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Splits command chains on operators (&&, ||, ;, |) while respecting:
|
|
94
|
+
* - Quoted strings (single and double) -- operators inside quotes are literal.
|
|
95
|
+
* - Escape sequences -- backslash-escaped characters are not treated as operators.
|
|
96
|
+
* - Command substitution -- $(...) and backtick blocks are treated as opaque.
|
|
97
|
+
* Nested $() is tracked via parenDepth to avoid premature splitting.
|
|
98
|
+
*
|
|
99
|
+
* Each returned string is a standalone command to validate independently.
|
|
100
|
+
*/
|
|
101
|
+
export function splitChainedCommands(command) {
|
|
102
|
+
const commands = [];
|
|
103
|
+
let current = '';
|
|
104
|
+
let inQuote = null;
|
|
105
|
+
let parenDepth = 0; // Track $(...) nesting
|
|
106
|
+
let backtickDepth = 0;
|
|
107
|
+
for (let i = 0; i < command.length; i++) {
|
|
108
|
+
const char = command[i];
|
|
109
|
+
const nextChar = command[i + 1];
|
|
110
|
+
// Handle escape sequences
|
|
111
|
+
if (char === '\\' && !inQuote && i + 1 < command.length) {
|
|
112
|
+
current += char + (nextChar ?? '');
|
|
113
|
+
i++;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (char === '\\' && inQuote === '"' && i + 1 < command.length) {
|
|
117
|
+
const next = nextChar ?? '';
|
|
118
|
+
if (next === '"' || next === '\\' || next === '$' || next === '`') {
|
|
119
|
+
current += char + next;
|
|
120
|
+
i++;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Track quote state
|
|
125
|
+
if (char === '"' && inQuote !== "'") {
|
|
126
|
+
inQuote = inQuote === '"' ? null : '"';
|
|
127
|
+
current += char;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (char === "'" && inQuote !== '"') {
|
|
131
|
+
inQuote = inQuote === "'" ? null : "'";
|
|
132
|
+
current += char;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
// Track command substitution: $( ... )
|
|
136
|
+
if (!inQuote && char === '$' && nextChar === '(') {
|
|
137
|
+
// Enter command substitution and consume both "$("
|
|
138
|
+
parenDepth++;
|
|
139
|
+
current += '$(';
|
|
140
|
+
i++;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (!inQuote && parenDepth > 0 && char === '(') {
|
|
144
|
+
// Nested parentheses inside $(...) - increment depth
|
|
145
|
+
parenDepth++;
|
|
146
|
+
current += char;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (!inQuote && char === ')' && parenDepth > 0) {
|
|
150
|
+
parenDepth--;
|
|
151
|
+
current += char;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
// Track backtick command substitution
|
|
155
|
+
if (!inQuote && char === '`') {
|
|
156
|
+
backtickDepth = backtickDepth > 0 ? 0 : 1;
|
|
157
|
+
current += char;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
// Only split on operators when not inside quotes or substitutions
|
|
161
|
+
if (!inQuote && parenDepth === 0 && backtickDepth === 0) {
|
|
162
|
+
if (char === ';') {
|
|
163
|
+
if (current.trim())
|
|
164
|
+
commands.push(current.trim());
|
|
165
|
+
current = '';
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if (char === '&' && nextChar === '&') {
|
|
169
|
+
if (current.trim())
|
|
170
|
+
commands.push(current.trim());
|
|
171
|
+
current = '';
|
|
172
|
+
i++; // Skip second &
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (char === '|' && nextChar === '|') {
|
|
176
|
+
if (current.trim())
|
|
177
|
+
commands.push(current.trim());
|
|
178
|
+
current = '';
|
|
179
|
+
i++; // Skip second |
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (char === '|') {
|
|
183
|
+
if (current.trim())
|
|
184
|
+
commands.push(current.trim());
|
|
185
|
+
current = '';
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
current += char;
|
|
190
|
+
}
|
|
191
|
+
if (current.trim())
|
|
192
|
+
commands.push(current.trim());
|
|
193
|
+
return commands;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Extracts the base binary name from a command string, respecting quotes
|
|
197
|
+
* and escape sequences.
|
|
198
|
+
*/
|
|
199
|
+
export function extractBaseCommand(command) {
|
|
200
|
+
const tokens = shellTokenize(command.trim());
|
|
201
|
+
if (tokens.length === 0)
|
|
202
|
+
return '';
|
|
203
|
+
// Skip common variable assignments (e.g., "FOO=bar cmd")
|
|
204
|
+
let cmdToken = tokens[0];
|
|
205
|
+
let idx = 0;
|
|
206
|
+
while (idx < tokens.length && /^[A-Za-z_][A-Za-z0-9_]*=/.test(tokens[idx])) {
|
|
207
|
+
idx++;
|
|
208
|
+
}
|
|
209
|
+
if (idx < tokens.length) {
|
|
210
|
+
cmdToken = tokens[idx];
|
|
211
|
+
}
|
|
212
|
+
return path.basename(cmdToken);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Determine if a bash command is read-only.
|
|
216
|
+
*/
|
|
217
|
+
export function isReadOnlyCommand(command) {
|
|
218
|
+
const base = extractBaseCommand(command);
|
|
219
|
+
if (READ_ONLY_COMMANDS.has(base))
|
|
220
|
+
return true;
|
|
221
|
+
// git status, git log, git diff are read-only
|
|
222
|
+
if (base === 'git') {
|
|
223
|
+
const parts = command.trim().split(/\s+/);
|
|
224
|
+
const subCommand = parts[1] ?? '';
|
|
225
|
+
if (['status', 'log', 'diff', 'show', 'branch', 'remote', 'tag'].includes(subCommand)) {
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=shell-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-validator.js","sourceRoot":"","sources":["../../src/security/shell-validator.ts"],"names":[],"mappings":"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"}
|
package/dist/skills/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC"}
|
package/dist/skills/index.js
CHANGED
package/dist/skills/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC"}
|
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SkillLoader — Scans
|
|
2
|
+
* SkillLoader — Scans skill directories for available skills.
|
|
3
3
|
*
|
|
4
|
-
* Zora v0.6: Skills are .
|
|
4
|
+
* Zora v0.6: Skills are .zora/skills/<name>/SKILL.md markdown files.
|
|
5
5
|
* The SDK loads and invokes them automatically via settingSources.
|
|
6
6
|
* This loader provides CLI introspection (list, info).
|
|
7
|
+
*
|
|
8
|
+
* TYPE-09: Three-layer precedence — project > global > built-in.
|
|
9
|
+
* First-match-wins deduplication ensures project skills override global,
|
|
10
|
+
* and global overrides built-in.
|
|
7
11
|
*/
|
|
12
|
+
export type SkillLayer = 'project' | 'global' | 'builtin';
|
|
8
13
|
export interface SkillInfo {
|
|
9
14
|
name: string;
|
|
10
15
|
description: string;
|
|
11
16
|
path: string;
|
|
12
17
|
}
|
|
18
|
+
export interface LayeredSkillInfo extends SkillInfo {
|
|
19
|
+
layer: SkillLayer;
|
|
20
|
+
}
|
|
13
21
|
/**
|
|
14
22
|
* Extracts a description from SKILL.md YAML frontmatter.
|
|
15
23
|
*/
|
|
@@ -22,4 +30,32 @@ export declare function parseSkillFrontmatter(content: string): {
|
|
|
22
30
|
* @returns Sorted array of SkillInfo
|
|
23
31
|
*/
|
|
24
32
|
export declare function loadSkills(skillsDir: string): Promise<SkillInfo[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Returns the default skill layer directories in precedence order.
|
|
35
|
+
* 1. Project — `.zora/skills/` relative to cwd
|
|
36
|
+
* 2. Global — `~/.zora/skills/`
|
|
37
|
+
* 3. Built-in — `skills/` inside the package root
|
|
38
|
+
*
|
|
39
|
+
* @param cwd Override for the current working directory (useful for testing)
|
|
40
|
+
*/
|
|
41
|
+
export declare function getSkillLayers(cwd?: string): Array<{
|
|
42
|
+
dir: string;
|
|
43
|
+
layer: SkillLayer;
|
|
44
|
+
}>;
|
|
45
|
+
/**
|
|
46
|
+
* Loads skills from all three precedence layers (project > global > built-in).
|
|
47
|
+
* First-match-wins: if a skill name appears in a higher-precedence layer,
|
|
48
|
+
* the lower-precedence version is excluded.
|
|
49
|
+
*
|
|
50
|
+
* @param options.cwd Override for project directory (defaults to process.cwd())
|
|
51
|
+
* @param options.layers Override the layer directories (useful for testing)
|
|
52
|
+
* @returns Sorted array of LayeredSkillInfo with layer annotation
|
|
53
|
+
*/
|
|
54
|
+
export declare function loadSkillsLayered(options?: {
|
|
55
|
+
cwd?: string;
|
|
56
|
+
layers?: Array<{
|
|
57
|
+
dir: string;
|
|
58
|
+
layer: SkillLayer;
|
|
59
|
+
}>;
|
|
60
|
+
}): Promise<LayeredSkillInfo[]>;
|
|
25
61
|
//# sourceMappingURL=skill-loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-loader.d.ts","sourceRoot":"","sources":["../../src/skills/skill-loader.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"skill-loader.d.ts","sourceRoot":"","sources":["../../src/skills/skill-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE1D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IACjD,KAAK,EAAE,UAAU,CAAC;CACnB;AAID;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAe9E;AAID;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CA6BxE;AAID;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC,CAUtF;AAqCD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,CAAC,EAAE;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;CACpD,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAgB9B"}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SkillLoader — Scans
|
|
2
|
+
* SkillLoader — Scans skill directories for available skills.
|
|
3
3
|
*
|
|
4
|
-
* Zora v0.6: Skills are .
|
|
4
|
+
* Zora v0.6: Skills are .zora/skills/<name>/SKILL.md markdown files.
|
|
5
5
|
* The SDK loads and invokes them automatically via settingSources.
|
|
6
6
|
* This loader provides CLI introspection (list, info).
|
|
7
|
+
*
|
|
8
|
+
* TYPE-09: Three-layer precedence — project > global > built-in.
|
|
9
|
+
* First-match-wins deduplication ensures project skills override global,
|
|
10
|
+
* and global overrides built-in.
|
|
7
11
|
*/
|
|
8
12
|
import fs from 'node:fs/promises';
|
|
9
13
|
import path from 'node:path';
|
|
14
|
+
import os from 'node:os';
|
|
10
15
|
// ─── Frontmatter Parser ─────────────────────────────────────────────
|
|
11
16
|
/**
|
|
12
17
|
* Extracts a description from SKILL.md YAML frontmatter.
|
|
@@ -61,4 +66,80 @@ export async function loadSkills(skillsDir) {
|
|
|
61
66
|
}
|
|
62
67
|
return skills.sort((a, b) => a.name.localeCompare(b.name));
|
|
63
68
|
}
|
|
69
|
+
// ─── Three-Layer Skill Precedence (TYPE-09) ─────────────────────────
|
|
70
|
+
/**
|
|
71
|
+
* Returns the default skill layer directories in precedence order.
|
|
72
|
+
* 1. Project — `.zora/skills/` relative to cwd
|
|
73
|
+
* 2. Global — `~/.zora/skills/`
|
|
74
|
+
* 3. Built-in — `skills/` inside the package root
|
|
75
|
+
*
|
|
76
|
+
* @param cwd Override for the current working directory (useful for testing)
|
|
77
|
+
*/
|
|
78
|
+
export function getSkillLayers(cwd) {
|
|
79
|
+
const projectDir = path.join(cwd ?? process.cwd(), '.zora', 'skills');
|
|
80
|
+
const globalDir = path.join(os.homedir(), '.zora', 'skills');
|
|
81
|
+
const builtinDir = path.resolve(path.join(path.dirname(import.meta.url.replace('file://', '')), '..', 'skills'));
|
|
82
|
+
return [
|
|
83
|
+
{ dir: projectDir, layer: 'project' },
|
|
84
|
+
{ dir: globalDir, layer: 'global' },
|
|
85
|
+
{ dir: builtinDir, layer: 'builtin' },
|
|
86
|
+
];
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Scans a single skills directory and returns LayeredSkillInfo entries.
|
|
90
|
+
*/
|
|
91
|
+
async function scanSkillLayer(skillsDir, layer) {
|
|
92
|
+
const skills = [];
|
|
93
|
+
let dirs;
|
|
94
|
+
try {
|
|
95
|
+
dirs = await fs.readdir(skillsDir);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return skills; // Directory doesn't exist
|
|
99
|
+
}
|
|
100
|
+
for (const dir of dirs) {
|
|
101
|
+
const skillPath = path.join(skillsDir, dir, 'SKILL.md');
|
|
102
|
+
try {
|
|
103
|
+
const stat = await fs.stat(path.join(skillsDir, dir));
|
|
104
|
+
if (!stat.isDirectory())
|
|
105
|
+
continue;
|
|
106
|
+
const content = await fs.readFile(skillPath, 'utf-8');
|
|
107
|
+
const { description } = parseSkillFrontmatter(content);
|
|
108
|
+
skills.push({
|
|
109
|
+
name: dir,
|
|
110
|
+
description: description || `Skill: ${dir}`,
|
|
111
|
+
path: skillPath,
|
|
112
|
+
layer,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// Skip directories without SKILL.md
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return skills;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Loads skills from all three precedence layers (project > global > built-in).
|
|
123
|
+
* First-match-wins: if a skill name appears in a higher-precedence layer,
|
|
124
|
+
* the lower-precedence version is excluded.
|
|
125
|
+
*
|
|
126
|
+
* @param options.cwd Override for project directory (defaults to process.cwd())
|
|
127
|
+
* @param options.layers Override the layer directories (useful for testing)
|
|
128
|
+
* @returns Sorted array of LayeredSkillInfo with layer annotation
|
|
129
|
+
*/
|
|
130
|
+
export async function loadSkillsLayered(options) {
|
|
131
|
+
const layers = options?.layers ?? getSkillLayers(options?.cwd);
|
|
132
|
+
const seen = new Set();
|
|
133
|
+
const result = [];
|
|
134
|
+
for (const { dir, layer } of layers) {
|
|
135
|
+
const skills = await scanSkillLayer(dir, layer);
|
|
136
|
+
for (const skill of skills) {
|
|
137
|
+
if (!seen.has(skill.name)) {
|
|
138
|
+
seen.add(skill.name);
|
|
139
|
+
result.push(skill);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return result.sort((a, b) => a.name.localeCompare(b.name));
|
|
144
|
+
}
|
|
64
145
|
//# sourceMappingURL=skill-loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-loader.js","sourceRoot":"","sources":["../../src/skills/skill-loader.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"skill-loader.js","sourceRoot":"","sources":["../../src/skills/skill-loader.ts"],"names":[],"mappings":"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"}
|