mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-29 21:33:54 +00:00
feat: tfcode
This commit is contained in:
parent
3fe808d64c
commit
8ecbe43e2d
99
PROGRESS.md
99
PROGRESS.md
@ -17,74 +17,57 @@ Build and deploy **tfcode** - ToothFairyAI's official AI coding agent, a fork of
|
|||||||
- Postinstall script checks if binary exists before downloading
|
- Postinstall script checks if binary exists before downloading
|
||||||
- ESM-compatible module resolution for npm fallback
|
- ESM-compatible module resolution for npm fallback
|
||||||
- Wrapper script fixed to look for binary in correct location
|
- Wrapper script fixed to look for binary in correct location
|
||||||
|
8. ✅ Fixed ToothFairyAI model support (v1.0.5)
|
||||||
|
- Disabled `thinking` parameters for TF models (API doesn't support yet)
|
||||||
|
- Disabled auto-update (managed via npm instead)
|
||||||
|
- Updated `upgrade` command to point to npm
|
||||||
|
- Tested with `mystica` model - working!
|
||||||
|
|
||||||
## Current Status
|
## Current Status
|
||||||
|
|
||||||
**Working**: npm installation flow is now fully functional. Users can install via:
|
**Working**: npm installation and ToothFairyAI models are fully functional.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install @toothfairyai/tfcode
|
npm install -g @toothfairyai/tfcode@latest
|
||||||
```
|
|
||||||
|
|
||||||
The binary is included in the main package, making installation instant without needing to download from Gitea or copy from optionalDependencies.
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
1. Build all platform binaries (12 targets: linux/darwin/windows × arm64/x64 × baseline/musl)
|
|
||||||
2. Test on different platforms (currently only darwin-arm64 is tested)
|
|
||||||
3. Create Gitea releases for backup download mechanism
|
|
||||||
4. Consider making Gitea repo public for transparency
|
|
||||||
|
|
||||||
## Technical Details
|
|
||||||
|
|
||||||
### npm Package Structure
|
|
||||||
|
|
||||||
The published package includes:
|
|
||||||
|
|
||||||
- `bin/tfcode` - The actual binary (92MB)
|
|
||||||
- `bin/tfcode.js` - Wrapper script that spawns the binary
|
|
||||||
- `postinstall.mjs` - Installation script (checks for binary, downloads if missing, installs Python SDK)
|
|
||||||
- `package.json` - Package metadata
|
|
||||||
- `LICENSE` - MIT license
|
|
||||||
|
|
||||||
### Installation Flow
|
|
||||||
|
|
||||||
1. npm installs main package + optionalDependencies
|
|
||||||
2. npm extracts files to `node_modules/@toothfairyai/tfcode/`
|
|
||||||
3. postinstall runs:
|
|
||||||
- Checks if binary already exists (✓ for darwin-arm64)
|
|
||||||
- If not, tries to download from Gitea
|
|
||||||
- If that fails, copies from optionalDependencies
|
|
||||||
- Installs Python SDK for TF integration
|
|
||||||
4. User can run `tfcode` command
|
|
||||||
|
|
||||||
### Key Fixes in v1.0.4
|
|
||||||
|
|
||||||
1. **Postinstall script**: Fixed duplicate variable declaration (`binaryName`)
|
|
||||||
2. **Postinstall script**: Added early return if binary already exists
|
|
||||||
3. **Postinstall script**: Fixed ESM module resolution (replaced `require.resolve` with `import.meta.resolve`)
|
|
||||||
4. **Publish script**: Copy current platform binary to main package
|
|
||||||
5. **Wrapper script**: Fixed binary path (removed extra `bin/` directory)
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Fresh installation test
|
|
||||||
rm -rf /tmp/tfcode-test && mkdir /tmp/tfcode-test
|
|
||||||
cd /tmp/tfcode-test && npm init -y
|
|
||||||
npm install @toothfairyai/tfcode
|
|
||||||
node_modules/.bin/tfcode --version # Should output: 1.0.4
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Version History
|
## Version History
|
||||||
|
|
||||||
|
- **1.0.5**: Fixed ToothFairyAI model support, disabled auto-update
|
||||||
- **1.0.4**: Fixed npm installation flow, binary included in main package
|
- **1.0.4**: Fixed npm installation flow, binary included in main package
|
||||||
- **1.0.3**: Initial npm publication (broken installation)
|
- **1.0.3**: Initial npm publication (broken installation)
|
||||||
- **1.0.2**: Earlier testing versions
|
|
||||||
- **1.0.0**: Initial release
|
|
||||||
|
|
||||||
## Credentials (Testing Only)
|
## Key Fixes
|
||||||
|
|
||||||
- workspace_id: `6586b7e6-683e-4ee6-a6cf-24c19729b5ff`
|
### v1.0.5 Changes
|
||||||
- api_key: `EWZooLROIS57EVW3BKGu7Pv6LNe4D6m4gkDjukx3`
|
|
||||||
- region: `dev`
|
1. **Provider transform**: Added early return for `@toothfairyai/sdk` to prevent sending `thinking` parameters
|
||||||
|
2. **Auto-update**: Hardcoded `OPENCODE_DISABLE_AUTOUPDATE = true`
|
||||||
|
3. **Upgrade command**: Now shows npm instructions instead of attempting self-update
|
||||||
|
|
||||||
|
### v1.0.4 Changes
|
||||||
|
|
||||||
|
1. **Postinstall script**: Fixed ESM module resolution, early return if binary exists
|
||||||
|
2. **Publish script**: Copy current platform binary to main package
|
||||||
|
3. **Wrapper script**: Fixed binary path lookup
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install
|
||||||
|
npm install -g @toothfairyai/tfcode@latest
|
||||||
|
|
||||||
|
# Set credentials
|
||||||
|
export TF_WORKSPACE_ID="your-workspace-id"
|
||||||
|
export TF_API_KEY="your-api-key"
|
||||||
|
export TF_REGION="dev" # or au, eu, us
|
||||||
|
|
||||||
|
# Test
|
||||||
|
tfcode run "say hello" --model toothfairyai/mystica
|
||||||
|
```
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
1. Build all platform binaries (12 targets)
|
||||||
|
2. Test on different platforms (currently only darwin-arm64)
|
||||||
|
3. Document available models (mystica, mystica_15, etc.)
|
||||||
|
|||||||
@ -1,73 +1,31 @@
|
|||||||
import type { Argv } from "yargs"
|
import type { Argv } from "yargs"
|
||||||
import { UI } from "../ui"
|
import { UI } from "../ui"
|
||||||
import * as prompts from "@clack/prompts"
|
import * as prompts from "@clack/prompts"
|
||||||
import { Installation } from "../../installation"
|
|
||||||
|
|
||||||
export const UpgradeCommand = {
|
export const UpgradeCommand = {
|
||||||
command: "upgrade [target]",
|
command: "upgrade [target]",
|
||||||
describe: "upgrade tfcode to the latest or a specific version",
|
describe: "upgrade tfcode to the latest or a specific version",
|
||||||
builder: (yargs: Argv) => {
|
builder: (yargs: Argv) => {
|
||||||
return yargs
|
return yargs.positional("target", {
|
||||||
.positional("target", {
|
describe: "version to upgrade to, for ex '1.0.5' or 'v1.0.5'",
|
||||||
describe: "version to upgrade to, for ex '0.1.48' or 'v0.1.48'",
|
type: "string",
|
||||||
type: "string",
|
})
|
||||||
})
|
|
||||||
.option("method", {
|
|
||||||
alias: "m",
|
|
||||||
describe: "installation method to use",
|
|
||||||
type: "string",
|
|
||||||
choices: ["curl", "npm", "pnpm", "bun", "brew", "choco", "scoop"],
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
handler: async (args: { target?: string; method?: string }) => {
|
handler: async (args: { target?: string }) => {
|
||||||
UI.empty()
|
UI.empty()
|
||||||
UI.println(UI.logo(" "))
|
UI.println(UI.logo(" "))
|
||||||
UI.empty()
|
UI.empty()
|
||||||
prompts.intro("Upgrade")
|
prompts.intro("Upgrade")
|
||||||
const detectedMethod = await Installation.method()
|
|
||||||
const method = (args.method as Installation.Method) ?? detectedMethod
|
|
||||||
if (method === "unknown") {
|
|
||||||
prompts.log.error(`tfcode is installed to ${process.execPath} and may be managed by a package manager`)
|
|
||||||
const install = await prompts.select({
|
|
||||||
message: "Install anyways?",
|
|
||||||
options: [
|
|
||||||
{ label: "Yes", value: true },
|
|
||||||
{ label: "No", value: false },
|
|
||||||
],
|
|
||||||
initialValue: false,
|
|
||||||
})
|
|
||||||
if (!install) {
|
|
||||||
prompts.outro("Done")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prompts.log.info("Using method: " + method)
|
|
||||||
const target = args.target ? args.target.replace(/^v/, "") : await Installation.latest()
|
|
||||||
|
|
||||||
if (Installation.VERSION === target) {
|
prompts.log.info("tfcode is managed via npm.")
|
||||||
prompts.log.warn(`tfcode upgrade skipped: ${target} is already installed`)
|
prompts.log.info("To upgrade, run:")
|
||||||
prompts.outro("Done")
|
prompts.log.info("")
|
||||||
return
|
prompts.log.info(" npm install -g @toothfairyai/tfcode@latest")
|
||||||
}
|
prompts.log.info("")
|
||||||
|
prompts.log.info("Or for a specific version:")
|
||||||
|
prompts.log.info("")
|
||||||
|
prompts.log.info(` npm install -g @toothfairyai/tfcode@${args.target || "1.0.5"}`)
|
||||||
|
|
||||||
prompts.log.info(`From ${Installation.VERSION} → ${target}`)
|
|
||||||
const spinner = prompts.spinner()
|
|
||||||
spinner.start("Upgrading...")
|
|
||||||
const err = await Installation.upgrade(method, target).catch((err) => err)
|
|
||||||
if (err) {
|
|
||||||
spinner.stop("Upgrade failed", 1)
|
|
||||||
if (err instanceof Installation.UpgradeFailedError) {
|
|
||||||
// necessary because choco only allows install/upgrade in elevated terminals
|
|
||||||
if (method === "choco" && err.stderr.includes("not running from an elevated command shell")) {
|
|
||||||
prompts.log.error("Please run the terminal as Administrator and try again")
|
|
||||||
} else {
|
|
||||||
prompts.log.error(err.stderr)
|
|
||||||
}
|
|
||||||
} else if (err instanceof Error) prompts.log.error(err.message)
|
|
||||||
prompts.outro("Done")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
spinner.stop("Upgrade complete")
|
|
||||||
prompts.outro("Done")
|
prompts.outro("Done")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export namespace Flag {
|
|||||||
export declare const OPENCODE_TUI_CONFIG: string | undefined
|
export declare const OPENCODE_TUI_CONFIG: string | undefined
|
||||||
export declare const OPENCODE_CONFIG_DIR: string | undefined
|
export declare const OPENCODE_CONFIG_DIR: string | undefined
|
||||||
export const OPENCODE_CONFIG_CONTENT = process.env["OPENCODE_CONFIG_CONTENT"]
|
export const OPENCODE_CONFIG_CONTENT = process.env["OPENCODE_CONFIG_CONTENT"]
|
||||||
export const OPENCODE_DISABLE_AUTOUPDATE = truthy("OPENCODE_DISABLE_AUTOUPDATE")
|
export const OPENCODE_DISABLE_AUTOUPDATE = true // Disabled for tfcode - updates managed via npm
|
||||||
export const OPENCODE_ALWAYS_NOTIFY_UPDATE = truthy("OPENCODE_ALWAYS_NOTIFY_UPDATE")
|
export const OPENCODE_ALWAYS_NOTIFY_UPDATE = truthy("OPENCODE_ALWAYS_NOTIFY_UPDATE")
|
||||||
export const OPENCODE_DISABLE_PRUNE = truthy("OPENCODE_DISABLE_PRUNE")
|
export const OPENCODE_DISABLE_PRUNE = truthy("OPENCODE_DISABLE_PRUNE")
|
||||||
export const OPENCODE_DISABLE_TERMINAL_TITLE = truthy("OPENCODE_DISABLE_TERMINAL_TITLE")
|
export const OPENCODE_DISABLE_TERMINAL_TITLE = truthy("OPENCODE_DISABLE_TERMINAL_TITLE")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user