mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-07 10:36:05 -10:00
- Licence notices: the embedded host bundle carries MIT-licensed packages (cordis, schemastery, cosmokit, dsh-util-values, dsh-tools excerpts). dist/LICENSES.txt is now generated at build time from the bundler's metafile and each package's own licence, embedded, and written beside the materialised bundle. THIRD_PARTY_NOTICES.md lists the packages. A test reads the package markers in the embedded bundle and requires a notice and a third-party entry for each. - Tool input is checked against the tool's registered JSON Schema before an approval card exists and again before the call is sent; an invalid input is a tool error the model can correct. A schema that cannot be compiled is refused at registration. jsonschema moves from a dev-dependency to a dependency of codewhale-tui (already in the lock file through codewhale-workflow-js; Cargo.lock unchanged). - A plugin with several native entries activates all of them under one owner; a failing entry fails the owner and the earlier entries are disposed. - Plugin context: tools and commands receive the calling workspace and a private per-plugin data directory. `[plugins."<name>".config]` in the user's config.toml reaches the plugin (16 KiB cap; project config cannot set it); a change starts a new generation; `/plugin show` lists the configured keys, never values. - `codewhale --enable/--disable <feature>` before a subcommand is passed through by the dispatcher instead of being rejected. - Docs and config comments: Linux sandbox wording, the 30 s handshake, the macOS sandbox write allowances. Known gaps: the trust review screen does not show config keys; a running session does not watch config.toml; no end-to-end launch of a rebuilt binary for the --enable fix. Verified by the committer on macOS, Rust 1.99, real Node 22.20 host: cargo fmt --all --check clean; CI-policy clippy on codewhale-tui and codewhale-cli clean; cargo test -p codewhale-tui --lib -- extension_host:: plugins:: commands::user_registry conformance:: integrations::dsh: 411 passed, 0 failed, 1 ignored; codewhale-cli lib: 475 passed, 0 failed; host suite on Node: 88 passed, 0 failed, 1 skipped. Reported by the implementing agent, not re-run: host suite on Bun 1.4.0, 89 passed. Linux, Windows and the Rust-side Bun tests unrun. Signed-off-by: CodeWhale Bot <[email protected]> Co-Authored-By: Claude Fable 5.1 <[email protected]>
52 lines
1.9 KiB
TypeScript
52 lines
1.9 KiB
TypeScript
// Node strips these erasable types; no compiler or package installation is needed.
|
|
// `@deepseek-ai/schemastery` is supplied by the host, not installed.
|
|
import Schema from '@deepseek-ai/schemastery'
|
|
|
|
type Input = { name?: string }
|
|
type Execution = { signal: AbortSignal; callId: string }
|
|
type Invocation = { args: string; signal: AbortSignal }
|
|
|
|
export const name = 'hello-extension'
|
|
export const inject = ['tools', 'commands']
|
|
|
|
// The one setting this example reads. The user sets it in their config.toml:
|
|
//
|
|
// [plugins."hello-extension".config]
|
|
// greeting = "Howdy"
|
|
//
|
|
// The host checks it against this schema before `apply` runs (a wrong type
|
|
// fails activation with the reason) and fills in the default when it is unset.
|
|
export const Config = Schema.object({
|
|
greeting: Schema.string().default('Hello'),
|
|
})
|
|
|
|
export function apply(ctx: any, config: { greeting: string }) {
|
|
ctx.tools.register({
|
|
name: 'hello_greet',
|
|
description: 'Return a greeting. This example does not read files or use the network.',
|
|
parameters: {
|
|
type: 'object',
|
|
properties: { name: { type: 'string' } },
|
|
additionalProperties: false,
|
|
},
|
|
execute(input: Input, exec: Execution) {
|
|
exec.signal.throwIfAborted()
|
|
return { greeting: `${config.greeting}, ${input.name ?? 'world'}!`, callId: exec.callId }
|
|
},
|
|
})
|
|
|
|
// `/hello-greet [name]`: a slash command the *user* runs. It can only
|
|
// answer: text shown in the transcript, or `{ kind: 'submit', prompt }` to
|
|
// send a prompt as the user's next message (the model's work after that
|
|
// goes through the normal turn and its approvals).
|
|
ctx.commands.register({
|
|
name: 'hello-greet',
|
|
description: 'Greet someone. This example does not read files or use the network.',
|
|
argumentHint: '[name]',
|
|
handler(invocation: Invocation) {
|
|
invocation.signal.throwIfAborted()
|
|
return { kind: 'success', text: `${config.greeting}, ${invocation.args || 'world'}!` }
|
|
},
|
|
})
|
|
}
|