@toothfairyai/tfcode 3.0.4 → 3.0.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/LICENSE +21 -0
- package/README.md +0 -0
- package/bin/tfcode.js +42 -504
- package/package.json +25 -162
- package/postinstall.mjs +236 -0
- package/python/tf_sync/__init__.py +21 -0
- package/python/tf_sync/agents.py +39 -0
- package/python/tf_sync/config.py +222 -0
- package/python/tf_sync/mcp.py +41 -0
- package/python/tf_sync/tools.py +282 -0
- package/bin/tfcode +0 -17
package/package.json
CHANGED
|
@@ -1,170 +1,33 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
-
"version": "3.0.4",
|
|
4
2
|
"name": "@toothfairyai/tfcode",
|
|
5
|
-
"
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"files": [
|
|
8
|
-
"bin",
|
|
9
|
-
"app",
|
|
10
|
-
"postinstall.mjs",
|
|
11
|
-
"LICENSE"
|
|
12
|
-
],
|
|
13
|
-
"scripts": {
|
|
14
|
-
"prepare": "effect-language-service patch || true",
|
|
15
|
-
"postinstall": "node scripts/postinstall.cjs",
|
|
16
|
-
"typecheck": "tsgo --noEmit",
|
|
17
|
-
"test": "bun test --timeout 30000",
|
|
18
|
-
"build": "bun run script/build-tfcode.ts",
|
|
19
|
-
"build:single": "bun run script/build-tfcode.ts --single",
|
|
20
|
-
"publish:upload": "bun run script/publish-tfcode.ts --upload",
|
|
21
|
-
"publish:npm": "bun run script/publish-tfcode.ts --npm",
|
|
22
|
-
"publish:brew": "bun run script/publish-tfcode.ts --brew",
|
|
23
|
-
"publish:all": "bun run script/publish-tfcode.ts --all",
|
|
24
|
-
"dev": "bun run --conditions=browser ./src/index.ts",
|
|
25
|
-
"db": "bun drizzle-kit"
|
|
26
|
-
},
|
|
3
|
+
"version": "3.0.6",
|
|
27
4
|
"bin": {
|
|
28
|
-
"tfcode": "./bin/tfcode"
|
|
5
|
+
"tfcode": "./bin/tfcode.js"
|
|
29
6
|
},
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
},
|
|
33
|
-
"imports": {
|
|
34
|
-
"#db": {
|
|
35
|
-
"bun": "./src/storage/db.bun.ts",
|
|
36
|
-
"node": "./src/storage/db.node.ts",
|
|
37
|
-
"default": "./src/storage/db.bun.ts"
|
|
38
|
-
}
|
|
7
|
+
"scripts": {
|
|
8
|
+
"postinstall": "node ./postinstall.mjs"
|
|
39
9
|
},
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
"@
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
47
|
-
"@
|
|
48
|
-
"@
|
|
49
|
-
"@
|
|
50
|
-
"@
|
|
51
|
-
"@
|
|
52
|
-
"@
|
|
53
|
-
"@
|
|
54
|
-
"@tsconfig/bun": "catalog:",
|
|
55
|
-
"@types/babel__core": "7.20.5",
|
|
56
|
-
"@types/bun": "1.3.11",
|
|
57
|
-
"@types/cross-spawn": "6.0.6",
|
|
58
|
-
"@types/mime-types": "3.0.1",
|
|
59
|
-
"@types/node": "22.13.9",
|
|
60
|
-
"@types/semver": "^7.5.8",
|
|
61
|
-
"@types/turndown": "5.0.5",
|
|
62
|
-
"@types/which": "3.0.4",
|
|
63
|
-
"@types/ws": "8.18.1",
|
|
64
|
-
"@types/yargs": "17.0.33",
|
|
65
|
-
"@typescript/native-preview": "catalog:",
|
|
66
|
-
"drizzle-kit": "catalog:",
|
|
67
|
-
"drizzle-orm": "catalog:",
|
|
68
|
-
"typescript": "catalog:",
|
|
69
|
-
"vscode-languageserver-types": "3.17.5",
|
|
70
|
-
"why-is-node-running": "3.2.2",
|
|
71
|
-
"zod-to-json-schema": "3.24.5"
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"optionalDependencies": {
|
|
12
|
+
"@toothfairyai/tfcode-linux-arm64": "3.0.6",
|
|
13
|
+
"@toothfairyai/tfcode-windows-x64": "3.0.6",
|
|
14
|
+
"@toothfairyai/tfcode-linux-x64-baseline-musl": "3.0.6",
|
|
15
|
+
"@toothfairyai/tfcode-darwin-x64-baseline": "3.0.6",
|
|
16
|
+
"@toothfairyai/tfcode-linux-x64-musl": "3.0.6",
|
|
17
|
+
"@toothfairyai/tfcode-windows-x64-baseline": "3.0.6",
|
|
18
|
+
"@toothfairyai/tfcode-linux-arm64-musl": "3.0.6",
|
|
19
|
+
"@toothfairyai/tfcode-windows-arm64": "3.0.6",
|
|
20
|
+
"@toothfairyai/tfcode-linux-x64": "3.0.6",
|
|
21
|
+
"@toothfairyai/tfcode-darwin-x64": "3.0.6",
|
|
22
|
+
"@toothfairyai/tfcode-linux-x64-baseline": "3.0.6",
|
|
23
|
+
"@toothfairyai/tfcode-darwin-arm64": "3.0.6"
|
|
72
24
|
},
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"@actions/github": "6.0.1",
|
|
76
|
-
"@agentclientprotocol/sdk": "0.14.1",
|
|
77
|
-
"@ai-sdk/amazon-bedrock": "3.0.82",
|
|
78
|
-
"@ai-sdk/anthropic": "2.0.65",
|
|
79
|
-
"@ai-sdk/azure": "2.0.91",
|
|
80
|
-
"@ai-sdk/cerebras": "1.0.36",
|
|
81
|
-
"@ai-sdk/cohere": "2.0.22",
|
|
82
|
-
"@ai-sdk/deepinfra": "1.0.36",
|
|
83
|
-
"@ai-sdk/gateway": "2.0.30",
|
|
84
|
-
"@ai-sdk/google": "2.0.54",
|
|
85
|
-
"@ai-sdk/google-vertex": "3.0.106",
|
|
86
|
-
"@ai-sdk/groq": "2.0.34",
|
|
87
|
-
"@ai-sdk/mistral": "2.0.27",
|
|
88
|
-
"@ai-sdk/openai": "2.0.89",
|
|
89
|
-
"@ai-sdk/openai-compatible": "1.0.32",
|
|
90
|
-
"@ai-sdk/perplexity": "2.0.23",
|
|
91
|
-
"@ai-sdk/provider": "2.0.1",
|
|
92
|
-
"@ai-sdk/provider-utils": "3.0.21",
|
|
93
|
-
"@ai-sdk/togetherai": "1.0.34",
|
|
94
|
-
"@ai-sdk/vercel": "1.0.33",
|
|
95
|
-
"@ai-sdk/xai": "2.0.51",
|
|
96
|
-
"@aws-sdk/credential-providers": "3.993.0",
|
|
97
|
-
"@clack/prompts": "1.0.0-alpha.1",
|
|
98
|
-
"@effect/platform-node": "catalog:",
|
|
99
|
-
"@hono/standard-validator": "0.1.5",
|
|
100
|
-
"@hono/zod-validator": "catalog:",
|
|
101
|
-
"@modelcontextprotocol/sdk": "1.29.0",
|
|
102
|
-
"@octokit/graphql": "9.0.2",
|
|
103
|
-
"@octokit/rest": "catalog:",
|
|
104
|
-
"@openauthjs/openauth": "catalog:",
|
|
105
|
-
"@opencode-ai/gateway": "workspace:*",
|
|
106
|
-
"@opencode-ai/plugin": "workspace:*",
|
|
107
|
-
"@opencode-ai/script": "workspace:*",
|
|
108
|
-
"@opencode-ai/sdk": "workspace:*",
|
|
109
|
-
"@opencode-ai/util": "workspace:*",
|
|
110
|
-
"@openrouter/ai-sdk-provider": "1.5.4",
|
|
111
|
-
"@opentui/core": "0.2.16",
|
|
112
|
-
"@opentui/solid": "0.2.16",
|
|
113
|
-
"@parcel/watcher": "2.5.1",
|
|
114
|
-
"@pierre/diffs": "catalog:",
|
|
115
|
-
"@solid-primitives/event-bus": "1.1.2",
|
|
116
|
-
"@solid-primitives/scheduled": "1.5.2",
|
|
117
|
-
"@standard-schema/spec": "1.0.0",
|
|
118
|
-
"@zip.js/zip.js": "2.7.62",
|
|
119
|
-
"ai": "catalog:",
|
|
120
|
-
"ai-gateway-provider": "2.3.1",
|
|
121
|
-
"bonjour-service": "1.3.0",
|
|
122
|
-
"bun-pty": "0.4.8",
|
|
123
|
-
"chokidar": "4.0.3",
|
|
124
|
-
"clipboardy": "4.0.0",
|
|
125
|
-
"croner": "10.0.1",
|
|
126
|
-
"cross-spawn": "^7.0.6",
|
|
127
|
-
"decimal.js": "10.5.0",
|
|
128
|
-
"diff": "catalog:",
|
|
129
|
-
"drizzle-orm": "catalog:",
|
|
130
|
-
"effect": "catalog:",
|
|
131
|
-
"fuzzysort": "3.1.0",
|
|
132
|
-
"gitlab-ai-provider": "5.2.2",
|
|
133
|
-
"glob": "13.0.5",
|
|
134
|
-
"google-auth-library": "10.5.0",
|
|
135
|
-
"gray-matter": "4.0.3",
|
|
136
|
-
"hono": "catalog:",
|
|
137
|
-
"hono-openapi": "catalog:",
|
|
138
|
-
"ignore": "7.0.5",
|
|
139
|
-
"jsonc-parser": "3.3.1",
|
|
140
|
-
"jszip": "3.10.2",
|
|
141
|
-
"marked": "catalog:",
|
|
142
|
-
"mime-types": "3.0.2",
|
|
143
|
-
"minimatch": "10.0.3",
|
|
144
|
-
"open": "10.1.2",
|
|
145
|
-
"opencode-gitlab-auth": "2.0.0",
|
|
146
|
-
"opentui-spinner": "0.0.6",
|
|
147
|
-
"partial-json": "0.1.7",
|
|
148
|
-
"react": "19.2.4",
|
|
149
|
-
"react-dom": "19.2.4",
|
|
150
|
-
"remeda": "catalog:",
|
|
151
|
-
"semver": "^7.6.3",
|
|
152
|
-
"solid-js": "catalog:",
|
|
153
|
-
"strip-ansi": "7.1.2",
|
|
154
|
-
"tree-sitter-bash": "0.25.0",
|
|
155
|
-
"tree-sitter-powershell": "0.25.10",
|
|
156
|
-
"turndown": "7.2.0",
|
|
157
|
-
"ulid": "catalog:",
|
|
158
|
-
"vscode-jsonrpc": "8.2.1",
|
|
159
|
-
"web-tree-sitter": "0.25.10",
|
|
160
|
-
"which": "6.0.1",
|
|
161
|
-
"ws": "8.21.0",
|
|
162
|
-
"xdg-basedir": "5.1.0",
|
|
163
|
-
"yargs": "18.0.0",
|
|
164
|
-
"zod": "catalog:",
|
|
165
|
-
"zod-to-json-schema": "3.24.5"
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18"
|
|
166
27
|
},
|
|
167
|
-
"
|
|
168
|
-
|
|
28
|
+
"homepage": "https://toothfairyai.com/developers/tfcode",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git"
|
|
169
32
|
}
|
|
170
|
-
}
|
|
33
|
+
}
|
package/postinstall.mjs
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "fs"
|
|
4
|
+
import path from "path"
|
|
5
|
+
import os from "os"
|
|
6
|
+
import { spawnSync } from "child_process"
|
|
7
|
+
import { fileURLToPath } from "url"
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
10
|
+
const __dirname = path.dirname(__filename)
|
|
11
|
+
|
|
12
|
+
function detectPlatform() {
|
|
13
|
+
let platform
|
|
14
|
+
switch (os.platform()) {
|
|
15
|
+
case "darwin":
|
|
16
|
+
platform = "darwin"
|
|
17
|
+
break
|
|
18
|
+
case "linux":
|
|
19
|
+
platform = "linux"
|
|
20
|
+
break
|
|
21
|
+
case "win32":
|
|
22
|
+
platform = "windows"
|
|
23
|
+
break
|
|
24
|
+
default:
|
|
25
|
+
platform = os.platform()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let arch
|
|
29
|
+
switch (os.arch()) {
|
|
30
|
+
case "x64":
|
|
31
|
+
arch = "x64"
|
|
32
|
+
break
|
|
33
|
+
case "arm64":
|
|
34
|
+
arch = "arm64"
|
|
35
|
+
break
|
|
36
|
+
default:
|
|
37
|
+
arch = os.arch()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Check for AVX2 on x64
|
|
41
|
+
let needsBaseline = false
|
|
42
|
+
if (arch === "x64" && (platform === "linux" || platform === "darwin")) {
|
|
43
|
+
try {
|
|
44
|
+
if (platform === "linux") {
|
|
45
|
+
const cpuinfo = fs.readFileSync("/proc/cpuinfo", "utf8")
|
|
46
|
+
needsBaseline = !cpuinfo.toLowerCase().includes("avx2")
|
|
47
|
+
} else if (platform === "darwin") {
|
|
48
|
+
const result = spawnSync("sysctl", ["-n", "hw.optional.avx2_0"], { encoding: "utf8" })
|
|
49
|
+
needsBaseline = result.stdout.trim() !== "1"
|
|
50
|
+
}
|
|
51
|
+
} catch {}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Check for musl on Linux
|
|
55
|
+
let abi = ""
|
|
56
|
+
if (platform === "linux") {
|
|
57
|
+
try {
|
|
58
|
+
if (fs.existsSync("/etc/alpine-release")) {
|
|
59
|
+
abi = "musl"
|
|
60
|
+
} else {
|
|
61
|
+
const result = spawnSync("ldd", ["--version"], { encoding: "utf8" })
|
|
62
|
+
if ((result.stdout + result.stderr).toLowerCase().includes("musl")) {
|
|
63
|
+
abi = "musl"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
} catch {}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return { platform, arch, needsBaseline, abi }
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function targetName() {
|
|
73
|
+
const { platform, arch, needsBaseline, abi } = detectPlatform()
|
|
74
|
+
let target = `tfcode-${platform}-${arch}`
|
|
75
|
+
if (needsBaseline) target += "-baseline"
|
|
76
|
+
if (abi) target += `-${abi}`
|
|
77
|
+
return target
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Copy bundled computer-use helper binaries (e.g. cliclick on macOS) from a
|
|
81
|
+
// source bin dir into the installed bin dir, so `tfcode computer setup` finds
|
|
82
|
+
// them next to the binary without Homebrew/apt. No-op when absent. npm may
|
|
83
|
+
// strip the exec bit, so chmod the helpers back to 0755.
|
|
84
|
+
function copyComputerAssets(srcBinDir, dstBinDir) {
|
|
85
|
+
const srcComputer = path.join(srcBinDir, "computer")
|
|
86
|
+
if (!fs.existsSync(srcComputer)) return
|
|
87
|
+
const dstComputer = path.join(dstBinDir, "computer")
|
|
88
|
+
if (fs.existsSync(dstComputer)) fs.rmSync(dstComputer, { recursive: true, force: true })
|
|
89
|
+
fs.cpSync(srcComputer, dstComputer, { recursive: true })
|
|
90
|
+
for (const name of fs.readdirSync(dstComputer)) {
|
|
91
|
+
try {
|
|
92
|
+
fs.chmodSync(path.join(dstComputer, name), 0o755)
|
|
93
|
+
} catch {}
|
|
94
|
+
}
|
|
95
|
+
console.log("✓ Computer-use helpers copied from platform package")
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// The binary ships in the platform-specific optionalDependency
|
|
99
|
+
// (@toothfairyai/tfcode-<platform>-<arch>[-baseline][-musl]). Link it into
|
|
100
|
+
// this package's bin/ dir and copy the web app + computer-use helpers.
|
|
101
|
+
function setupFromPlatformPackage() {
|
|
102
|
+
const { platform } = detectPlatform()
|
|
103
|
+
const pkgName = `@toothfairyai/${targetName()}`
|
|
104
|
+
const binaryName = platform === "windows" ? "tfcode.exe" : "tfcode"
|
|
105
|
+
const binDir = path.join(__dirname, "bin")
|
|
106
|
+
|
|
107
|
+
// ESM-compatible module resolution
|
|
108
|
+
let pkgDir
|
|
109
|
+
try {
|
|
110
|
+
const pkgUrl = import.meta.resolve(`${pkgName}/package.json`)
|
|
111
|
+
const pkgPath = fileURLToPath(pkgUrl)
|
|
112
|
+
pkgDir = path.dirname(pkgPath)
|
|
113
|
+
} catch (e) {
|
|
114
|
+
console.error(`Could not resolve ${pkgName}: ${e.message}`)
|
|
115
|
+
console.error("")
|
|
116
|
+
console.error("The platform package for your machine was not installed.")
|
|
117
|
+
console.error("")
|
|
118
|
+
console.error("Possible solutions:")
|
|
119
|
+
console.error(` 1. Install it explicitly: npm install ${pkgName}`)
|
|
120
|
+
console.error(" 2. Clear the npm cache and reinstall: npm cache clean --force && npm install @toothfairyai/tfcode")
|
|
121
|
+
console.error(" 3. Contact ToothFairyAI support for assistance")
|
|
122
|
+
console.error("")
|
|
123
|
+
process.exit(1)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const sourceBinary = path.join(pkgDir, "bin", binaryName)
|
|
127
|
+
if (!fs.existsSync(sourceBinary)) {
|
|
128
|
+
console.error(`Binary not found at ${sourceBinary}`)
|
|
129
|
+
process.exit(1)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Link (or copy) the binary into bin/
|
|
133
|
+
if (!fs.existsSync(binDir)) fs.mkdirSync(binDir, { recursive: true })
|
|
134
|
+
const targetBinary = path.join(binDir, binaryName)
|
|
135
|
+
if (fs.existsSync(targetBinary)) fs.unlinkSync(targetBinary)
|
|
136
|
+
try {
|
|
137
|
+
fs.linkSync(sourceBinary, targetBinary)
|
|
138
|
+
} catch {
|
|
139
|
+
fs.copyFileSync(sourceBinary, targetBinary)
|
|
140
|
+
}
|
|
141
|
+
fs.chmodSync(targetBinary, 0o755)
|
|
142
|
+
console.log(`tfcode installed to ${targetBinary}`)
|
|
143
|
+
|
|
144
|
+
// Copy app dir
|
|
145
|
+
const srcAppDir = path.join(pkgDir, "bin", "app")
|
|
146
|
+
const targetAppDir = path.join(binDir, "app")
|
|
147
|
+
if (fs.existsSync(path.join(srcAppDir, "dist", "index.html"))) {
|
|
148
|
+
if (fs.existsSync(targetAppDir)) fs.rmSync(targetAppDir, { recursive: true, force: true })
|
|
149
|
+
fs.cpSync(srcAppDir, targetAppDir, { recursive: true })
|
|
150
|
+
console.log("Web app copied from platform package")
|
|
151
|
+
} else {
|
|
152
|
+
console.log("! Web app not found in platform package")
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
copyComputerAssets(path.join(pkgDir, "bin"), binDir)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function main() {
|
|
159
|
+
console.log("")
|
|
160
|
+
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
|
161
|
+
console.log(" tfcode - ToothFairyAI's official coding agent")
|
|
162
|
+
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
|
163
|
+
console.log("")
|
|
164
|
+
|
|
165
|
+
// Setup binary from the npm platform package
|
|
166
|
+
setupFromPlatformPackage()
|
|
167
|
+
|
|
168
|
+
// Check for Python (needed for TF integration)
|
|
169
|
+
try {
|
|
170
|
+
const result = spawnSync("python3", ["--version"], { encoding: "utf8" })
|
|
171
|
+
if (result.status === 0) {
|
|
172
|
+
console.log(`✓ Found ${result.stdout.trim()}`)
|
|
173
|
+
|
|
174
|
+
// Install Python SDK
|
|
175
|
+
console.log("Installing ToothFairyAI Python SDK...")
|
|
176
|
+
const pipResult = spawnSync(
|
|
177
|
+
"python3",
|
|
178
|
+
["-m", "pip", "install", "--user", "--break-system-packages", "toothfairyai", "pydantic", "httpx", "rich"],
|
|
179
|
+
{
|
|
180
|
+
stdio: "inherit",
|
|
181
|
+
},
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
if (pipResult.status === 0) {
|
|
185
|
+
console.log("✓ Python SDK installed")
|
|
186
|
+
} else {
|
|
187
|
+
console.log("! Python SDK install failed, run manually:")
|
|
188
|
+
console.log(" pip install toothfairyai pydantic httpx rich")
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} catch {
|
|
192
|
+
console.log("! Python 3.10+ not found. Install with:")
|
|
193
|
+
console.log(" macOS: brew install python@3.12")
|
|
194
|
+
console.log(" Ubuntu: sudo apt install python3.12")
|
|
195
|
+
console.log(" Windows: Download from python.org/downloads")
|
|
196
|
+
console.log("")
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
console.log("")
|
|
200
|
+
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
|
201
|
+
console.log("✓ tfcode installed successfully!")
|
|
202
|
+
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
|
|
203
|
+
console.log("")
|
|
204
|
+
console.log("Quick Start:")
|
|
205
|
+
console.log("")
|
|
206
|
+
console.log(" 1. Set credentials:")
|
|
207
|
+
console.log(' export TF_WORKSPACE_ID="your-workspace-id"')
|
|
208
|
+
console.log(' export TF_API_KEY="your-api-key"')
|
|
209
|
+
console.log("")
|
|
210
|
+
console.log(" 2. Validate:")
|
|
211
|
+
console.log(" tfcode validate")
|
|
212
|
+
console.log("")
|
|
213
|
+
console.log(" 3. Sync tools:")
|
|
214
|
+
console.log(" tfcode sync")
|
|
215
|
+
console.log("")
|
|
216
|
+
console.log(" 4. Start coding:")
|
|
217
|
+
console.log(" tfcode")
|
|
218
|
+
console.log("")
|
|
219
|
+
// Optional feature — keep it short and clearly labeled so the coding-first
|
|
220
|
+
// Quick Start isn't noised up. Point npm installers at the one-command setup.
|
|
221
|
+
const cuPlatform = os.platform()
|
|
222
|
+
const cuHint =
|
|
223
|
+
cuPlatform === "darwin"
|
|
224
|
+
? "a permissions dialog will appear (Accessibility & Screen Recording); cliclick is bundled."
|
|
225
|
+
: cuPlatform === "win32"
|
|
226
|
+
? "no extra installs needed — pre-compiles the input helper."
|
|
227
|
+
: "installs xdotool + a screenshot tool via your package manager."
|
|
228
|
+
console.log(" Computer use (optional — control the OS GUI: mouse, keyboard, screen):")
|
|
229
|
+
console.log(" tfcode computer setup " + cuHint)
|
|
230
|
+
console.log(" tfcode computer doctor verify it works")
|
|
231
|
+
console.log("")
|
|
232
|
+
console.log("Documentation: https://toothfairyai.com/developers/tfcode")
|
|
233
|
+
console.log("")
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
main().catch(console.error)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
tf-sync: ToothFairyAI workspace sync layer for tfcode
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from tf_sync.agents import sync_agents
|
|
6
|
+
from tf_sync.mcp import sync_mcp_servers
|
|
7
|
+
from tf_sync.tools import sync_tools, ToolType
|
|
8
|
+
from tf_sync.config import TFConfig, load_config, validate_credentials, get_region_urls
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"sync_agents",
|
|
12
|
+
"sync_mcp_servers",
|
|
13
|
+
"sync_tools",
|
|
14
|
+
"ToolType",
|
|
15
|
+
"TFConfig",
|
|
16
|
+
"load_config",
|
|
17
|
+
"validate_credentials",
|
|
18
|
+
"get_region_urls",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Agent sync module for tfcode.
|
|
3
|
+
|
|
4
|
+
NOTE: This module is reserved for future implementation.
|
|
5
|
+
Currently, tfcode only syncs tools (MCP, Skills, Database, Functions).
|
|
6
|
+
Agent sync will be added in a later phase.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from pydantic import BaseModel
|
|
12
|
+
|
|
13
|
+
from tf_sync.config import TFConfig
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AgentSyncResult(BaseModel):
|
|
17
|
+
"""Result of agent sync operation."""
|
|
18
|
+
|
|
19
|
+
success: bool
|
|
20
|
+
agents: list[dict[str, Any]] = []
|
|
21
|
+
error: str | None = None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def sync_agents(config: TFConfig) -> AgentSyncResult:
|
|
25
|
+
"""
|
|
26
|
+
Sync agents from ToothFairyAI workspace.
|
|
27
|
+
|
|
28
|
+
NOTE: Currently not implemented. Reserved for future use.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
config: TFConfig instance
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
AgentSyncResult (currently always returns not implemented)
|
|
35
|
+
"""
|
|
36
|
+
return AgentSyncResult(
|
|
37
|
+
success=False,
|
|
38
|
+
error="Agent sync not yet implemented. Use tools sync for now.",
|
|
39
|
+
)
|