@soederpop/luca 0.0.21 → 0.0.22
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/luca.cli.ts +14 -1
- package/package.json +1 -1
- package/src/bootstrap/generated.ts +1 -1
- package/src/cli/cli.ts +45 -6
- package/src/commands/prompt.ts +14 -1
- package/src/introspection/generated.agi.ts +1207 -872
- package/src/introspection/generated.node.ts +841 -506
- package/src/introspection/generated.web.ts +1 -1
- package/src/node/container.ts +31 -1
- package/src/node/features/google-auth.ts +1 -0
- package/src/node/features/google-calendar.ts +5 -0
- package/src/node/features/google-docs.ts +8 -1
- package/src/node/features/google-drive.ts +6 -0
- package/src/node/features/google-mail.ts +540 -0
- package/src/node/features/google-sheets.ts +6 -0
- package/src/scaffolds/generated.ts +1 -1
package/luca.cli.ts
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
-
export async function main(container) {
|
|
1
|
+
export async function main(container: any) {
|
|
2
2
|
container.addContext('luca', container)
|
|
3
|
+
|
|
4
|
+
try {
|
|
5
|
+
container.onMissingCommand(handleMissingCommand)
|
|
6
|
+
} catch(error) {
|
|
7
|
+
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
async function handleMissingCommand({ words, phrase } : { words: string[], phrase: string }) {
|
|
12
|
+
const { ui } = container
|
|
13
|
+
|
|
14
|
+
ui.print.red('oh shit ' + phrase)
|
|
15
|
+
}
|
|
3
16
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soederpop/luca",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
4
|
"website": "https://luca.soederpop.com",
|
|
5
5
|
"description": "lightweight universal conversational architecture AKA Le Ultimate Component Architecture AKA Last Universal Common Ancestor, part AI part Human",
|
|
6
6
|
"author": "jon soeder aka the people's champ <jon@soederpop.com>",
|
package/src/cli/cli.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { join } from 'path'
|
|
|
19
19
|
async function main() {
|
|
20
20
|
const profile = process.env.LUCA_PROFILE === '1'
|
|
21
21
|
const t = (label?: string) => {
|
|
22
|
-
if (!profile) return () => {}
|
|
22
|
+
if (!profile) return () => { }
|
|
23
23
|
const start = performance.now()
|
|
24
24
|
return (suffix?: string) => {
|
|
25
25
|
const ms = (performance.now() - start).toFixed(1)
|
|
@@ -59,8 +59,8 @@ async function main() {
|
|
|
59
59
|
const afterUser = new Set(container.commands.available as string[])
|
|
60
60
|
const userCommands = new Set([...afterUser].filter((n) => !builtinCommands.has(n) && !projectCommands.has(n)))
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
// Store command sources for help display
|
|
63
|
+
; (container as any)._commandSources = { builtinCommands, projectCommands, userCommands }
|
|
64
64
|
|
|
65
65
|
// Load generated introspection data if present
|
|
66
66
|
done = t('loadProjectIntrospection')
|
|
@@ -82,9 +82,33 @@ async function main() {
|
|
|
82
82
|
await cmd.dispatch()
|
|
83
83
|
} else if (commandName) {
|
|
84
84
|
// not a known command — treat as implicit `run`
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
//
|
|
86
|
+
if (resolveScript(commandName, container)) {
|
|
87
|
+
container.argv._.splice(0, 0, 'run')
|
|
88
|
+
const cmd = container.command('run' as any)
|
|
89
|
+
await cmd.dispatch()
|
|
90
|
+
} else {
|
|
91
|
+
|
|
92
|
+
// @ts-ignore TODO come up with a typesafe way to do this
|
|
93
|
+
if (container.state.get('missingCommandHandler')) {
|
|
94
|
+
// @ts-ignore TODO come up with a typesafe way to do this
|
|
95
|
+
const missingCommandHandler = container.state.get('missingCommandHandler') as any
|
|
96
|
+
|
|
97
|
+
if (typeof missingCommandHandler === 'function') {
|
|
98
|
+
await missingCommandHandler({
|
|
99
|
+
words: container.argv._,
|
|
100
|
+
phrase: container.argv._.join(' ')
|
|
101
|
+
}).catch((err: any) => {
|
|
102
|
+
console.error(`Missing command handler error: ${err.message}`, err)
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
container.argv._.splice(0, 0, 'help')
|
|
107
|
+
const cmd = container.command('help' as any)
|
|
108
|
+
await cmd.dispatch()
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
88
112
|
} else {
|
|
89
113
|
container.argv._.splice(0, 0, 'help')
|
|
90
114
|
const cmd = container.command('help' as any)
|
|
@@ -94,6 +118,21 @@ async function main() {
|
|
|
94
118
|
tTotal()
|
|
95
119
|
}
|
|
96
120
|
|
|
121
|
+
function resolveScript(ref: string, container: any) {
|
|
122
|
+
const candidates = [
|
|
123
|
+
ref,
|
|
124
|
+
`${ref}.ts`,
|
|
125
|
+
`${ref}.js`,
|
|
126
|
+
`${ref}.md`,
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
for (const candidate of candidates) {
|
|
130
|
+
const resolved = container.paths.resolve(candidate)
|
|
131
|
+
if (container.fs.exists(resolved)) return resolved
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return null
|
|
135
|
+
}
|
|
97
136
|
|
|
98
137
|
async function loadCliModule() {
|
|
99
138
|
const modulePath = container.paths.resolve('luca.cli.ts')
|
package/src/commands/prompt.ts
CHANGED
|
@@ -12,7 +12,7 @@ declare module '../command.js' {
|
|
|
12
12
|
|
|
13
13
|
export const argsSchema = CommandOptionsSchema.extend({
|
|
14
14
|
model: z.string().optional().describe('Override the LLM model (assistant mode only)'),
|
|
15
|
-
'preserve-frontmatter': z.boolean().default(false).describe('Keep YAML frontmatter in the prompt instead of stripping it'),
|
|
15
|
+
'preserve-frontmatter': z.boolean().default(false).describe('Keep YAML frontmatter in the prompt instead of stripping it before sending to the agent.'),
|
|
16
16
|
'permission-mode': z.enum(['default', 'acceptEdits', 'bypassPermissions', 'plan']).default('acceptEdits').describe('Permission mode for CLI agents (default: acceptEdits)'),
|
|
17
17
|
'in-folder': z.string().optional().describe('Run the CLI agent in this directory (resolved via container.paths)'),
|
|
18
18
|
'out-file': z.string().optional().describe('Save session output as a markdown file'),
|
|
@@ -22,8 +22,16 @@ export const argsSchema = CommandOptionsSchema.extend({
|
|
|
22
22
|
'exclude-sections': z.string().optional().describe('Comma-separated list of section headings to exclude from the prompt'),
|
|
23
23
|
'chrome': z.boolean().default(false).describe('Launch Claude Code with a Chrome browser tool'),
|
|
24
24
|
'dry-run': z.boolean().default(false).describe('Display the resolved prompt and options without running the assistant'),
|
|
25
|
+
'local': z.boolean().default(false).describe('Use local models for assistant mode'),
|
|
25
26
|
})
|
|
26
27
|
|
|
28
|
+
function normalizeTarget(raw: string): string {
|
|
29
|
+
const lower = raw.toLowerCase().replace(/[-_]/g, '')
|
|
30
|
+
if (/claude/.test(lower)) return 'claude'
|
|
31
|
+
if (/codex/.test(lower) || /openai/.test(lower)) return 'codex'
|
|
32
|
+
return raw
|
|
33
|
+
}
|
|
34
|
+
|
|
27
35
|
const CLI_TARGETS = new Set(['claude', 'codex'])
|
|
28
36
|
|
|
29
37
|
function formatSessionMarkdown(events: any[], includeOutput: boolean): string {
|
|
@@ -163,6 +171,7 @@ async function runAssistant(name: string, promptContent: string, options: z.infe
|
|
|
163
171
|
const createOptions: Record<string, any> = { ...agentOptions }
|
|
164
172
|
// CLI flags override agentOptions from frontmatter
|
|
165
173
|
if (options.model) createOptions.model = options.model
|
|
174
|
+
if (options.local) createOptions.local = true
|
|
166
175
|
|
|
167
176
|
const assistant = manager.create(name, createOptions)
|
|
168
177
|
let isFirstChunk = true
|
|
@@ -360,6 +369,7 @@ async function runParallel(
|
|
|
360
369
|
const assistants = prepared.map((p, i) => {
|
|
361
370
|
const createOptions: Record<string, any> = { ...p.agentOptions }
|
|
362
371
|
if (options.model) createOptions.model = options.model
|
|
372
|
+
if (options.local) createOptions.local = true
|
|
363
373
|
const assistant = manager.create(target, createOptions)
|
|
364
374
|
|
|
365
375
|
assistant.on('chunk', (text: string) => {
|
|
@@ -831,6 +841,9 @@ export default async function prompt(options: z.infer<typeof argsSchema>, contex
|
|
|
831
841
|
}
|
|
832
842
|
}
|
|
833
843
|
|
|
844
|
+
// Normalize target aliases (e.g. claude-code → claude, openai-codex → codex)
|
|
845
|
+
if (target) target = normalizeTarget(target)
|
|
846
|
+
|
|
834
847
|
if (!target || allPaths.length === 0) {
|
|
835
848
|
console.error('Usage: luca prompt [claude|codex|assistant-name] <path/to/prompt.md> [more paths...]')
|
|
836
849
|
process.exit(1)
|