luca 3.0.0 → 3.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/.github/workflows/release.yaml +1 -0
- package/CLAUDE.md +10 -2
- package/README.md +130 -112
- package/assistants/codingAssistant/CORE.md +6 -1
- package/assistants/codingAssistant/hooks.ts +1 -1
- package/assistants/inkbot/hooks.ts +1 -1
- package/assistants/inkbot/tools.ts +1 -1
- package/bun.lock +264 -321
- package/commands/audit-docs.ts +2 -2
- package/commands/build-bootstrap.ts +2 -3
- package/commands/build-python-bridge.ts +2 -3
- package/commands/build-scaffolds.ts +2 -3
- package/commands/bundle-consumer-project.ts +521 -0
- package/commands/generate-api-docs.ts +2 -2
- package/commands/inkbot.ts +2 -2
- package/commands/release.ts +2 -2
- package/commands/social.ts +137 -0
- package/commands/try-all-challenges.ts +3 -3
- package/commands/try-challenge.ts +3 -3
- package/datasets/lora/agentic-loop-session-candidates.jsonl +91 -0
- package/datasets/lora/agentic-loop-session-curation-summary.json +123 -0
- package/datasets/lora/luca-session-candidates.jsonl +29 -0
- package/datasets/lora/luca-session-curation-summary.json +121 -0
- package/datasets/lora/review-batch-1.jsonl +30 -0
- package/datasets/lora/review-manifest.json +41 -0
- package/datasets/lora/review-queue.jsonl +120 -0
- package/datasets/lora/review-schema.json +134 -0
- package/datasets/lora/review-template.jsonl +2 -0
- package/datasets/lora/review-ui.html +725 -0
- package/dist/agi/container.server.d.ts +2 -2
- package/dist/agi/features/assistant.d.ts +2 -2
- package/dist/agi/features/assistants-manager.d.ts +1 -1
- package/dist/agi/features/autonomous-assistant.d.ts +1 -1
- package/dist/agi/features/browser-use.d.ts +1 -1
- package/dist/agi/features/claude-code.d.ts +1 -1
- package/dist/agi/features/conversation-history.d.ts +2 -2
- package/dist/agi/features/conversation.d.ts +1 -1
- package/dist/agi/features/docs-reader.d.ts +1 -1
- package/dist/agi/features/file-tools.d.ts +1 -1
- package/dist/agi/features/luca-coder.d.ts +1 -1
- package/dist/agi/features/openai-codex.d.ts +1 -1
- package/dist/agi/features/skills-library.d.ts +1 -1
- package/dist/clients/civitai/index.d.ts +4 -4
- package/dist/clients/client-template.d.ts +4 -4
- package/dist/clients/comfyui/index.d.ts +2 -2
- package/dist/clients/elevenlabs/index.d.ts +2 -2
- package/dist/clients/openai/index.d.ts +2 -2
- package/dist/clients/supabase/index.d.ts +3 -3
- package/dist/command.d.ts +1 -1
- package/dist/node/container.d.ts +1 -1
- package/dist/node/features/helpers.d.ts +3 -3
- package/dist/node/features/semantic-search.d.ts +1 -1
- package/dist/node/features/vm.d.ts +3 -3
- package/dist/node.d.ts +1 -1
- package/dist/scaffolds/generated.d.ts +1 -1
- package/dist/selector.d.ts +1 -1
- package/features/cipher-social.ts +493 -0
- package/index.html +217 -190
- package/luca.console.ts +1 -1
- package/package.json +7 -2
- package/public/index.html +217 -190
- package/public/slides-ai-native.html +1 -1
- package/public/slides-intro.html +2 -2
- package/scripts/curate-claude-sessions.ts +561 -0
- package/scripts/examples/ask-luca-expert.ts +1 -1
- package/scripts/examples/assistant-questions.ts +1 -1
- package/scripts/examples/excalidraw-expert.ts +1 -1
- package/scripts/examples/file-manager.ts +1 -1
- package/scripts/examples/ideas.ts +1 -1
- package/scripts/examples/interactive-chat.ts +1 -1
- package/scripts/examples/opening-a-web-browser.ts +1 -1
- package/scripts/examples/telegram-bot.ts +1 -1
- package/scripts/examples/using-assistant-with-mcp.ts +1 -1
- package/scripts/examples/using-claude-code.ts +1 -1
- package/scripts/examples/using-contentdb.ts +2 -2
- package/scripts/examples/using-conversations.ts +1 -1
- package/scripts/examples/using-disk-cache.ts +1 -1
- package/scripts/examples/using-docker-shell.ts +1 -1
- package/scripts/examples/using-elevenlabs.ts +1 -1
- package/scripts/examples/using-google-calendar.ts +1 -1
- package/scripts/examples/using-google-docs.ts +1 -1
- package/scripts/examples/using-google-drive.ts +1 -1
- package/scripts/examples/using-google-sheets.ts +1 -1
- package/scripts/examples/using-nlp.ts +1 -1
- package/scripts/examples/using-ollama.ts +1 -1
- package/scripts/examples/using-postgres.ts +1 -1
- package/scripts/examples/using-runpod.ts +1 -1
- package/scripts/examples/using-tts.ts +1 -1
- package/scripts/scaffold.ts +5 -5
- package/scripts/scratch.ts +1 -1
- package/scripts/test-assistant-hooks.ts +1 -1
- package/scripts/test-docs-reader.ts +1 -1
- package/src/agi/container.server.ts +6 -2
- package/src/agi/features/agent-memory.ts +25 -25
- package/src/agi/features/assistant.ts +34 -5
- package/src/agi/features/assistants-manager.ts +122 -6
- package/src/agi/features/autonomous-assistant.ts +1 -1
- package/src/agi/features/browser-use.ts +20 -1
- package/src/agi/features/claude-code.ts +51 -5
- package/src/agi/features/coding-tools.ts +1 -1
- package/src/agi/features/conversation-history.ts +181 -4
- package/src/agi/features/conversation.ts +186 -15
- package/src/agi/features/docs-reader.ts +2 -2
- package/src/agi/features/file-tools.ts +49 -2
- package/src/agi/features/luca-coder.ts +7 -5
- package/src/agi/features/mcp-bridge.ts +532 -0
- package/src/agi/features/openai-codex.ts +2 -2
- package/src/agi/features/skills-library.ts +131 -52
- package/src/agi/lib/token-counter.ts +80 -0
- package/src/bootstrap/generated.ts +56 -57
- package/src/browser.ts +1 -1
- package/src/cli/build-info.ts +2 -2
- package/src/cli/cli.ts +2 -2
- package/src/clients/civitai/index.ts +5 -5
- package/src/clients/client-template.ts +4 -4
- package/src/clients/comfyui/index.ts +4 -4
- package/src/clients/elevenlabs/index.ts +4 -4
- package/src/clients/openai/index.ts +7 -7
- package/src/clients/supabase/index.ts +4 -4
- package/src/clients/voicebox/index.ts +4 -4
- package/src/command.ts +2 -1
- package/src/commands/chat.ts +1 -0
- package/src/commands/eval.ts +2 -56
- package/src/commands/introspect.ts +1 -1
- package/src/commands/prompt.ts +41 -9
- package/src/container-describer.ts +8 -1
- package/src/container.ts +13 -0
- package/src/entity.ts +2 -2
- package/src/helper.ts +1 -1
- package/src/introspection/generated.agi.ts +29596 -27654
- package/src/introspection/generated.node.ts +20284 -19247
- package/src/introspection/generated.web.ts +605 -584
- package/src/introspection/scan.ts +11 -6
- package/src/node/container.ts +9 -1
- package/src/node/features/content-db.ts +39 -2
- package/src/node/features/display-result.ts +57 -0
- package/src/node/features/helpers.ts +46 -7
- package/src/node/features/python.ts +25 -19
- package/src/node/features/repl.ts +1 -1
- package/src/node/features/secure-shell.ts +11 -17
- package/src/node/features/semantic-search.ts +2 -2
- package/src/node/features/socket-repl.ts +336 -0
- package/src/node/features/telnyx-assistant-connector.ts +1206 -0
- package/src/node/features/transpiler.ts +2 -3
- package/src/node/features/ui.ts +5 -0
- package/src/node/features/vm.ts +20 -3
- package/src/node.ts +3 -3
- package/src/python/generated.ts +0 -1
- package/src/scaffolds/generated.ts +82 -83
- package/src/selector.ts +1 -1
- package/src/servers/express.ts +1 -1
- package/src/web/features/helpers.ts +22 -0
- package/tsconfig.json +12 -12
- package/docs/CLI.md +0 -335
- package/docs/CNAME +0 -1
- package/docs/README.md +0 -60
- package/docs/TABLE-OF-CONTENTS.md +0 -183
- package/docs/apis/clients/elevenlabs.md +0 -308
- package/docs/apis/clients/graph.md +0 -107
- package/docs/apis/clients/openai.md +0 -429
- package/docs/apis/clients/rest.md +0 -161
- package/docs/apis/clients/websocket.md +0 -174
- package/docs/apis/features/agi/assistant.md +0 -625
- package/docs/apis/features/agi/assistants-manager.md +0 -282
- package/docs/apis/features/agi/auto-assistant.md +0 -279
- package/docs/apis/features/agi/browser-use.md +0 -802
- package/docs/apis/features/agi/claude-code.md +0 -884
- package/docs/apis/features/agi/conversation-history.md +0 -364
- package/docs/apis/features/agi/conversation.md +0 -548
- package/docs/apis/features/agi/docs-reader.md +0 -99
- package/docs/apis/features/agi/file-tools.md +0 -163
- package/docs/apis/features/agi/luca-coder.md +0 -407
- package/docs/apis/features/agi/openai-codex.md +0 -396
- package/docs/apis/features/agi/openapi.md +0 -138
- package/docs/apis/features/agi/semantic-search.md +0 -387
- package/docs/apis/features/agi/skills-library.md +0 -239
- package/docs/apis/features/node/container-link.md +0 -192
- package/docs/apis/features/node/content-db.md +0 -450
- package/docs/apis/features/node/disk-cache.md +0 -379
- package/docs/apis/features/node/dns.md +0 -652
- package/docs/apis/features/node/docker.md +0 -706
- package/docs/apis/features/node/downloader.md +0 -81
- package/docs/apis/features/node/esbuild.md +0 -60
- package/docs/apis/features/node/file-manager.md +0 -191
- package/docs/apis/features/node/fs.md +0 -1217
- package/docs/apis/features/node/git.md +0 -371
- package/docs/apis/features/node/google-auth.md +0 -193
- package/docs/apis/features/node/google-calendar.md +0 -202
- package/docs/apis/features/node/google-docs.md +0 -173
- package/docs/apis/features/node/google-drive.md +0 -246
- package/docs/apis/features/node/google-mail.md +0 -214
- package/docs/apis/features/node/google-sheets.md +0 -194
- package/docs/apis/features/node/grep.md +0 -292
- package/docs/apis/features/node/helpers.md +0 -164
- package/docs/apis/features/node/ink.md +0 -334
- package/docs/apis/features/node/ipc-socket.md +0 -249
- package/docs/apis/features/node/json-tree.md +0 -86
- package/docs/apis/features/node/networking.md +0 -316
- package/docs/apis/features/node/nlp.md +0 -133
- package/docs/apis/features/node/opener.md +0 -97
- package/docs/apis/features/node/os.md +0 -146
- package/docs/apis/features/node/package-finder.md +0 -392
- package/docs/apis/features/node/postgres.md +0 -234
- package/docs/apis/features/node/proc.md +0 -399
- package/docs/apis/features/node/process-manager.md +0 -305
- package/docs/apis/features/node/python.md +0 -604
- package/docs/apis/features/node/redis.md +0 -380
- package/docs/apis/features/node/repl.md +0 -88
- package/docs/apis/features/node/runpod.md +0 -674
- package/docs/apis/features/node/secure-shell.md +0 -176
- package/docs/apis/features/node/semantic-search.md +0 -408
- package/docs/apis/features/node/sqlite.md +0 -233
- package/docs/apis/features/node/telegram.md +0 -279
- package/docs/apis/features/node/transpiler.md +0 -74
- package/docs/apis/features/node/tts.md +0 -133
- package/docs/apis/features/node/ui.md +0 -701
- package/docs/apis/features/node/vault.md +0 -59
- package/docs/apis/features/node/vm.md +0 -75
- package/docs/apis/features/node/yaml-tree.md +0 -85
- package/docs/apis/features/node/yaml.md +0 -176
- package/docs/apis/features/web/asset-loader.md +0 -59
- package/docs/apis/features/web/container-link.md +0 -192
- package/docs/apis/features/web/esbuild.md +0 -54
- package/docs/apis/features/web/helpers.md +0 -164
- package/docs/apis/features/web/network.md +0 -44
- package/docs/apis/features/web/speech.md +0 -69
- package/docs/apis/features/web/vault.md +0 -59
- package/docs/apis/features/web/vm.md +0 -75
- package/docs/apis/features/web/voice.md +0 -84
- package/docs/apis/servers/express.md +0 -171
- package/docs/apis/servers/mcp.md +0 -238
- package/docs/apis/servers/websocket.md +0 -170
- package/docs/bootstrap/CLAUDE.md +0 -101
- package/docs/bootstrap/SKILL.md +0 -341
- package/docs/bootstrap/templates/about-command.ts +0 -41
- package/docs/bootstrap/templates/docs-models.ts +0 -22
- package/docs/bootstrap/templates/docs-readme.md +0 -43
- package/docs/bootstrap/templates/example-feature.ts +0 -53
- package/docs/bootstrap/templates/health-endpoint.ts +0 -15
- package/docs/bootstrap/templates/luca-cli.ts +0 -30
- package/docs/bootstrap/templates/runme.md +0 -54
- package/docs/challenges/caching-proxy.md +0 -16
- package/docs/challenges/content-db-round-trip.md +0 -14
- package/docs/challenges/custom-command.md +0 -9
- package/docs/challenges/file-watcher-pipeline.md +0 -11
- package/docs/challenges/grep-audit-report.md +0 -15
- package/docs/challenges/multi-feature-dashboard.md +0 -14
- package/docs/challenges/process-orchestrator.md +0 -17
- package/docs/challenges/rest-api-server-with-client.md +0 -12
- package/docs/challenges/script-runner-with-vm.md +0 -11
- package/docs/challenges/simple-rest-api.md +0 -15
- package/docs/challenges/websocket-serve-and-client.md +0 -11
- package/docs/challenges/yaml-config-system.md +0 -14
- package/docs/command-system-overhaul.md +0 -94
- package/docs/documentation-audit.md +0 -134
- package/docs/examples/assistant/CORE.md +0 -18
- package/docs/examples/assistant/hooks.ts +0 -3
- package/docs/examples/assistant/tools.ts +0 -10
- package/docs/examples/assistant-hooks-reference.ts +0 -171
- package/docs/examples/assistant-with-process-manager.md +0 -84
- package/docs/examples/content-db.md +0 -77
- package/docs/examples/disk-cache.md +0 -83
- package/docs/examples/docker.md +0 -101
- package/docs/examples/downloader.md +0 -70
- package/docs/examples/entity.md +0 -124
- package/docs/examples/esbuild.md +0 -80
- package/docs/examples/feature-as-tool-provider.md +0 -143
- package/docs/examples/file-manager.md +0 -82
- package/docs/examples/fs.md +0 -83
- package/docs/examples/git.md +0 -85
- package/docs/examples/google-auth.md +0 -88
- package/docs/examples/google-calendar.md +0 -94
- package/docs/examples/google-docs.md +0 -82
- package/docs/examples/google-drive.md +0 -96
- package/docs/examples/google-sheets.md +0 -95
- package/docs/examples/grep.md +0 -85
- package/docs/examples/ink-blocks.md +0 -75
- package/docs/examples/ink-renderer.md +0 -41
- package/docs/examples/ink.md +0 -103
- package/docs/examples/ipc-socket.md +0 -103
- package/docs/examples/json-tree.md +0 -91
- package/docs/examples/networking.md +0 -58
- package/docs/examples/nlp.md +0 -91
- package/docs/examples/opener.md +0 -78
- package/docs/examples/os.md +0 -72
- package/docs/examples/package-finder.md +0 -89
- package/docs/examples/postgres.md +0 -91
- package/docs/examples/proc.md +0 -81
- package/docs/examples/process-manager.md +0 -79
- package/docs/examples/python.md +0 -132
- package/docs/examples/repl.md +0 -93
- package/docs/examples/runpod.md +0 -119
- package/docs/examples/secure-shell.md +0 -92
- package/docs/examples/sqlite.md +0 -86
- package/docs/examples/structured-output-with-assistants.md +0 -144
- package/docs/examples/telegram.md +0 -77
- package/docs/examples/tts.md +0 -86
- package/docs/examples/ui.md +0 -80
- package/docs/examples/vault.md +0 -70
- package/docs/examples/vm.md +0 -86
- package/docs/examples/websocket-ask-and-reply-example.md +0 -128
- package/docs/examples/yaml-tree.md +0 -93
- package/docs/examples/yaml.md +0 -104
- package/docs/ideas/assistant-factory-pattern.md +0 -142
- package/docs/in-memory-fs.md +0 -4
- package/docs/introspection-audit.md +0 -49
- package/docs/introspection.md +0 -164
- package/docs/mcp/readme.md +0 -162
- package/docs/models.ts +0 -41
- package/docs/philosophy.md +0 -86
- package/docs/principles.md +0 -7
- package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +0 -34
- package/docs/prompts/check-for-undocumented-features.md +0 -27
- package/docs/prompts/mcp-test-easy-command.md +0 -27
- package/docs/scaffolds/client.md +0 -149
- package/docs/scaffolds/command.md +0 -120
- package/docs/scaffolds/endpoint.md +0 -171
- package/docs/scaffolds/feature.md +0 -158
- package/docs/scaffolds/selector.md +0 -91
- package/docs/scaffolds/server.md +0 -196
- package/docs/selectors.md +0 -115
- package/docs/sessions/custom-command/attempt-log-2.md +0 -195
- package/docs/sessions/file-watcher-pipeline/attempt-log-1.md +0 -728
- package/docs/sessions/file-watcher-pipeline/attempt-log-2.md +0 -555
- package/docs/sessions/grep-audit-report/attempt-log-1.md +0 -289
- package/docs/sessions/multi-feature-dashboard/attempt-log-2.md +0 -679
- package/docs/sessions/rest-api-server-with-client/attempt-log-1.md +0 -1
- package/docs/sessions/rest-api-server-with-client/attempt-log-3.md +0 -920
- package/docs/sessions/simple-rest-api/attempt-log-1.md +0 -593
- package/docs/sessions/websocket-serve-and-client/attempt-log-2.md +0 -995
- package/docs/tutorials/00-bootstrap.md +0 -166
- package/docs/tutorials/01-getting-started.md +0 -106
- package/docs/tutorials/02-container.md +0 -210
- package/docs/tutorials/03-scripts.md +0 -194
- package/docs/tutorials/04-features-overview.md +0 -196
- package/docs/tutorials/05-state-and-events.md +0 -171
- package/docs/tutorials/06-servers.md +0 -157
- package/docs/tutorials/07-endpoints.md +0 -198
- package/docs/tutorials/08-commands.md +0 -252
- package/docs/tutorials/09-clients.md +0 -162
- package/docs/tutorials/10-creating-features.md +0 -203
- package/docs/tutorials/11-contentbase.md +0 -191
- package/docs/tutorials/12-assistants.md +0 -215
- package/docs/tutorials/13-introspection.md +0 -157
- package/docs/tutorials/14-type-system.md +0 -174
- package/docs/tutorials/15-project-patterns.md +0 -222
- package/docs/tutorials/16-google-features.md +0 -534
- package/docs/tutorials/17-tui-blocks.md +0 -530
- package/docs/tutorials/18-semantic-search.md +0 -334
- package/docs/tutorials/19-python-sessions.md +0 -401
- package/docs/tutorials/20-browser-esm.md +0 -234
- package/index.ts +0 -1
- package/src/agi/endpoints/ask.ts +0 -60
- package/src/agi/endpoints/conversations/[id].ts +0 -45
- package/src/agi/endpoints/conversations.ts +0 -31
- package/src/agi/endpoints/experts.ts +0 -37
- package/test/assistant-hooks.test.ts +0 -306
- package/test/assistant.test.ts +0 -81
- package/test/bus.test.ts +0 -134
- package/test/clients-servers.test.ts +0 -217
- package/test/command.test.ts +0 -267
- package/test/container-link.test.ts +0 -274
- package/test/conversation.test.ts +0 -220
- package/test/features.test.ts +0 -160
- package/test/fork-and-research.test.ts +0 -450
- package/test/integration.test.ts +0 -787
- package/test/interceptor-chain.test.ts +0 -61
- package/test/node-container.test.ts +0 -121
- package/test/python-session.test.ts +0 -105
- package/test/rate-limit.test.ts +0 -272
- package/test/semantic-search.test.ts +0 -550
- package/test/state.test.ts +0 -121
- package/test/vm-context.test.ts +0 -146
- package/test/vm-loadmodule.test.ts +0 -213
- package/test/websocket-ask.test.ts +0 -101
- package/test-integration/assistant.test.ts +0 -138
- package/test-integration/assistants-manager.test.ts +0 -113
- package/test-integration/claude-code.test.ts +0 -98
- package/test-integration/conversation-history.test.ts +0 -205
- package/test-integration/conversation.test.ts +0 -137
- package/test-integration/elevenlabs.test.ts +0 -55
- package/test-integration/google-services.test.ts +0 -80
- package/test-integration/helpers.ts +0 -89
- package/test-integration/memory.test.ts +0 -204
- package/test-integration/openai-codex.test.ts +0 -93
- package/test-integration/runpod.test.ts +0 -58
- package/test-integration/server-endpoints.test.ts +0 -97
- package/test-integration/telegram.test.ts +0 -46
|
@@ -5,14 +5,17 @@ import type { FS } from '../../node/features/fs.js'
|
|
|
5
5
|
import type { Grep, GrepMatch } from '../../node/features/grep.js'
|
|
6
6
|
import type { Helper } from '../../helper.js'
|
|
7
7
|
|
|
8
|
-
declare module '
|
|
8
|
+
declare module 'luca/feature' {
|
|
9
9
|
interface AvailableFeatures {
|
|
10
10
|
fileTools: typeof FileTools
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export const FileToolsStateSchema = FeatureStateSchema.extend({})
|
|
15
|
-
export const FileToolsOptionsSchema = FeatureOptionsSchema.extend({
|
|
15
|
+
export const FileToolsOptionsSchema = FeatureOptionsSchema.extend({
|
|
16
|
+
lockToFolder: z.string().optional().describe('When set, all file operations are restricted to this folder. Paths outside it are rejected.'),
|
|
17
|
+
forbid: z.array(z.union([z.string(), z.instanceof(RegExp)])).optional().describe('Patterns (strings or RegExps) that block access to any matching path.'),
|
|
18
|
+
})
|
|
16
19
|
|
|
17
20
|
/**
|
|
18
21
|
* Curated file-system and code-search tools for AI assistants.
|
|
@@ -133,11 +136,43 @@ export class FileTools extends Feature {
|
|
|
133
136
|
return this.container.feature('grep') as unknown as Grep
|
|
134
137
|
}
|
|
135
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Resolve a user-supplied path to an absolute path and validate it against
|
|
141
|
+
* `lockToFolder` and `forbid` constraints. Throws if the path is blocked.
|
|
142
|
+
*/
|
|
143
|
+
private validatePath(inputPath: string): string {
|
|
144
|
+
const resolved = this.container.paths.resolve(inputPath)
|
|
145
|
+
|
|
146
|
+
const { lockToFolder, forbid } = this.options as { lockToFolder?: string; forbid?: (string | RegExp)[] }
|
|
147
|
+
|
|
148
|
+
if (lockToFolder) {
|
|
149
|
+
const folder = this.container.paths.resolve(lockToFolder)
|
|
150
|
+
// The resolved path must be inside the locked folder (or be the folder itself)
|
|
151
|
+
if (resolved !== folder && !resolved.startsWith(folder + '/')) {
|
|
152
|
+
throw new Error(`Access denied: "${inputPath}" is outside the allowed folder "${lockToFolder}"`)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (forbid && forbid.length) {
|
|
157
|
+
for (const pattern of forbid) {
|
|
158
|
+
const matches = pattern instanceof RegExp
|
|
159
|
+
? pattern.test(resolved)
|
|
160
|
+
: resolved.includes(pattern)
|
|
161
|
+
if (matches) {
|
|
162
|
+
throw new Error(`Access denied: "${inputPath}" matches forbidden pattern "${pattern}"`)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return resolved
|
|
168
|
+
}
|
|
169
|
+
|
|
136
170
|
// -------------------------------------------------------------------------
|
|
137
171
|
// Tool implementations — each matches a static tools key by name
|
|
138
172
|
// -------------------------------------------------------------------------
|
|
139
173
|
|
|
140
174
|
async readFile(args: { path: string; offset?: number; limit?: number }): Promise<string> {
|
|
175
|
+
this.validatePath(args.path)
|
|
141
176
|
const content = await this.fs.readFileAsync(args.path) as string
|
|
142
177
|
|
|
143
178
|
if (args.offset || args.limit) {
|
|
@@ -151,12 +186,14 @@ export class FileTools extends Feature {
|
|
|
151
186
|
}
|
|
152
187
|
|
|
153
188
|
async writeFile(args: { path: string; content: string }): Promise<string> {
|
|
189
|
+
this.validatePath(args.path)
|
|
154
190
|
await this.fs.ensureFolderAsync(args.path.includes('/') ? args.path.split('/').slice(0, -1).join('/') : '.')
|
|
155
191
|
await this.fs.writeFileAsync(args.path, args.content)
|
|
156
192
|
return `Wrote ${args.content.length} bytes to ${args.path}`
|
|
157
193
|
}
|
|
158
194
|
|
|
159
195
|
async editFile(args: { path: string; oldString: string; newString: string; replaceAll?: boolean }): Promise<string> {
|
|
196
|
+
this.validatePath(args.path)
|
|
160
197
|
const content = await this.fs.readFileAsync(args.path) as string
|
|
161
198
|
|
|
162
199
|
if (args.replaceAll) {
|
|
@@ -183,6 +220,7 @@ export class FileTools extends Feature {
|
|
|
183
220
|
|
|
184
221
|
async listDirectory(args: { path?: string; recursive?: boolean; include?: string; exclude?: string }): Promise<string> {
|
|
185
222
|
const dir = args.path || '.'
|
|
223
|
+
this.validatePath(dir)
|
|
186
224
|
const result = await this.fs.walkAsync(dir, {
|
|
187
225
|
files: true,
|
|
188
226
|
directories: true,
|
|
@@ -201,6 +239,7 @@ export class FileTools extends Feature {
|
|
|
201
239
|
}
|
|
202
240
|
|
|
203
241
|
async searchFiles(args: { pattern: string; path?: string; include?: string; exclude?: string; ignoreCase?: boolean; maxResults?: number }): Promise<string> {
|
|
242
|
+
if (args.path) this.validatePath(args.path)
|
|
204
243
|
const results: GrepMatch[] = await this.grep.search({
|
|
205
244
|
pattern: args.pattern,
|
|
206
245
|
path: args.path,
|
|
@@ -219,6 +258,7 @@ export class FileTools extends Feature {
|
|
|
219
258
|
|
|
220
259
|
async findFiles(args: { pattern: string; path?: string; exclude?: string }): Promise<string> {
|
|
221
260
|
const dir = args.path || '.'
|
|
261
|
+
this.validatePath(dir)
|
|
222
262
|
const result = await this.fs.walkAsync(dir, {
|
|
223
263
|
files: true,
|
|
224
264
|
directories: false,
|
|
@@ -230,6 +270,7 @@ export class FileTools extends Feature {
|
|
|
230
270
|
}
|
|
231
271
|
|
|
232
272
|
async fileInfo(args: { path: string }): Promise<string> {
|
|
273
|
+
this.validatePath(args.path)
|
|
233
274
|
const exists = await this.fs.existsAsync(args.path)
|
|
234
275
|
if (!exists) return JSON.stringify({ exists: false })
|
|
235
276
|
|
|
@@ -244,21 +285,27 @@ export class FileTools extends Feature {
|
|
|
244
285
|
}
|
|
245
286
|
|
|
246
287
|
async createDirectory(args: { path: string }): Promise<string> {
|
|
288
|
+
this.validatePath(args.path)
|
|
247
289
|
await this.fs.ensureFolderAsync(args.path)
|
|
248
290
|
return `Created ${args.path}`
|
|
249
291
|
}
|
|
250
292
|
|
|
251
293
|
async moveFile(args: { source: string; destination: string }): Promise<string> {
|
|
294
|
+
this.validatePath(args.source)
|
|
295
|
+
this.validatePath(args.destination)
|
|
252
296
|
await this.fs.moveAsync(args.source, args.destination)
|
|
253
297
|
return `Moved ${args.source} → ${args.destination}`
|
|
254
298
|
}
|
|
255
299
|
|
|
256
300
|
async copyFile(args: { source: string; destination: string }): Promise<string> {
|
|
301
|
+
this.validatePath(args.source)
|
|
302
|
+
this.validatePath(args.destination)
|
|
257
303
|
await this.fs.copyAsync(args.source, args.destination)
|
|
258
304
|
return `Copied ${args.source} → ${args.destination}`
|
|
259
305
|
}
|
|
260
306
|
|
|
261
307
|
async deleteFile(args: { path: string }): Promise<string> {
|
|
308
|
+
this.validatePath(args.path)
|
|
262
309
|
const isDir = await this.fs.isDirectoryAsync(args.path)
|
|
263
310
|
if (isDir) return `Error: "${args.path}" is a directory. Use deleteFile only for files.`
|
|
264
311
|
await this.fs.rm(args.path)
|
|
@@ -4,7 +4,7 @@ import { Feature } from '../feature.js'
|
|
|
4
4
|
import type { Assistant } from './assistant.js'
|
|
5
5
|
import type { ToolCallCtx } from '../lib/interceptor-chain.js'
|
|
6
6
|
|
|
7
|
-
declare module '
|
|
7
|
+
declare module 'luca/feature' {
|
|
8
8
|
interface AvailableFeatures {
|
|
9
9
|
lucaCoder: typeof LucaCoder
|
|
10
10
|
}
|
|
@@ -104,8 +104,8 @@ export const LucaCoderOptionsSchema = FeatureOptionsSchema.extend({
|
|
|
104
104
|
/** Skills to auto-load into the system prompt context. If not specified, auto-detects luca-framework. */
|
|
105
105
|
skills: z.array(z.string()).optional().describe('Skill names to auto-load into the system prompt'),
|
|
106
106
|
|
|
107
|
-
/** Whether to auto-detect and load the luca-framework skill. Defaults to true. */
|
|
108
|
-
autoLoadLucaSkill: z.boolean().default(true).describe('Auto-load luca-framework skill if found in .claude/skills
|
|
107
|
+
/** Whether to auto-detect and load the luca-framework skill from conventional agent skill folders. Defaults to true. */
|
|
108
|
+
autoLoadLucaSkill: z.boolean().default(true).describe('Auto-load luca-framework skill if found in agent skill folders (.claude/skills or .agents/skills)'),
|
|
109
109
|
})
|
|
110
110
|
|
|
111
111
|
export type LucaCoderState = z.infer<typeof LucaCoderStateSchema>
|
|
@@ -116,7 +116,7 @@ export type LucaCoderOptions = z.infer<typeof LucaCoderOptionsSchema>
|
|
|
116
116
|
* gates all tool calls through a permission system.
|
|
117
117
|
*
|
|
118
118
|
* Comes with built-in Bash tool (via proc.execAndCapture) and auto-loads
|
|
119
|
-
* the luca-framework skill when found in .claude/skills
|
|
119
|
+
* the luca-framework skill when found in conventional agent skill folders (.claude/skills or .agents/skills).
|
|
120
120
|
*
|
|
121
121
|
* Tools are stacked from feature bundles (fileTools, etc.)
|
|
122
122
|
* and each tool can be set to 'allow' (runs immediately), 'ask' (blocks
|
|
@@ -415,11 +415,13 @@ export class LucaCoder extends Feature<LucaCoderState, LucaCoderOptions> {
|
|
|
415
415
|
const skillContent: string[] = []
|
|
416
416
|
const loadedSkills: string[] = []
|
|
417
417
|
|
|
418
|
-
// Check for luca-framework skill in
|
|
418
|
+
// Check for luca-framework skill in conventional agent skill folders
|
|
419
419
|
if (this.options.autoLoadLucaSkill !== false) {
|
|
420
420
|
const skillLocations = [
|
|
421
421
|
paths.resolve(this.container.cwd, '.claude', 'skills', 'luca-framework', 'SKILL.md'),
|
|
422
|
+
paths.resolve(this.container.cwd, '.agents', 'skills', 'luca-framework', 'SKILL.md'),
|
|
422
423
|
paths.resolve(os.homedir, '.claude', 'skills', 'luca-framework', 'SKILL.md'),
|
|
424
|
+
paths.resolve(os.homedir, '.agents', 'skills', 'luca-framework', 'SKILL.md'),
|
|
423
425
|
]
|
|
424
426
|
|
|
425
427
|
for (const skillPath of skillLocations) {
|