fcode-core-concepts
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFactorial Code core concepts
Factorial Code核心概念
Factorial Code (fcode) is an enterprise integration and automation platform.
You write processes (and reusable modules) in JavaScript or Python; the
platform handles sandboxing, dependencies, secrets, scheduling, and execution.
This skill is the mental model. For writing actual code, also use
or ; for the CLI workflow, .
fcode-javascriptfcode-pythonfcode-cliFactorial Code(fcode)是一款企业集成与自动化平台。您可以使用JavaScript或Python编写Process及可复用的Module;平台会处理沙箱隔离、依赖管理、密钥安全、调度与执行等工作。
本技能为您提供核心认知模型。如需编写实际代码,请使用或;如需CLI工作流,请使用。
fcode-javascriptfcode-pythonfcode-cliGotchas
注意事项(Gotchas)
These defy reasonable assumptions — get them wrong and the process breaks:
- Datastore stores only strings and numbers. Serialize objects with
/
JSON.stringifybeforejson.dumps, and parse onset.get - Module files are named after their slug, not /
index. A module lives atmain(ormodules/<slug>/<slug>.js) — e.g..py. Nevermodules/shopify-client/shopify-client.jsormodules/<slug>/index.js(those names are reserved for process entry files), and never put a module file directly undermain.pywithout its own folder.modules/ - Never overwrite the whole . Read it first and append/patch only the specific variable(s); rewriting the file drops every variable not in the new content and can break other processes.
variables.env - Never edit . It is regenerated on every pull and owned by the parent workspace. To change an inherited value for this workspace, add the key to
variables.inherited.env— that overrides it.variables.env - Never hardcode or log secrets. Use variables/env vars; mask or omit secrets from logs.
- Runtimes are pinned: JavaScript = Node.js v22, Python = 3.13.
以下内容不符合常规认知,若处理错误会导致流程中断:
- Datastore仅存储字符串和数字。调用前需使用
set/JSON.stringify序列化对象,调用json.dumps后再解析。get - Module文件需以其slug命名,而非/
index。Module需存放于main(或modules/<slug>/<slug>.js)路径下——例如.py。绝对不要使用modules/shopify-client/shopify-client.js或modules/<slug>/index.js(这些名称为Process入口文件保留),也绝对不要将Module文件直接放在main.py目录下而不创建独立文件夹。modules/ - 绝对不要覆盖整个文件。请先读取文件内容,仅追加/修改特定变量;重写文件会丢失所有未包含在新内容中的变量,可能导致其他流程中断。
variables.env - 绝对不要编辑文件。该文件会在每次拉取时重新生成,归父工作空间所有。如需修改当前工作空间的继承变量值,请将对应键添加到
variables.inherited.env中——这会覆盖继承的值。variables.env - 绝对不要硬编码或记录密钥。请使用变量/环境变量;在日志中屏蔽或省略密钥。
- 运行时版本固定:JavaScript对应Node.js v22,Python对应3.13。
Key concepts
核心概念
| Concept | What it is | Key point |
|---|---|---|
| Process | The unit of execution (business logic) | Defines input parameters, returns structured results |
| Module | Reusable code library | Shared across processes, can be versioned |
| Workspace version | One tag (e.g. | Published from the web UI; retrying the same tag is safe |
| Version alias | Movable pointer to a version | |
| Variables | Configuration & secrets | Env vars; inherited from parent workspaces; never hardcode secrets |
| Datastore | Persistent key-value store | Strings and numbers only |
| Storage | File storage | Binary files, documents, large payloads |
| Locales | Per-language translation files ( | Resolved by |
| Built-in transactional email | |
| 概念 | 定义 | 关键点 |
|---|---|---|
| Process | 执行单元(业务逻辑载体) | 定义输入参数,返回结构化结果 |
| Module | 可复用代码库 | 跨流程共享,支持版本控制 |
| Workspace version | 团队所有的每个Process和Module发布时使用的标签(如 | 通过Web UI发布;重试相同标签是安全操作 |
| Version alias | 指向版本的可移动指针 | |
| Variables | 配置与密钥 | 环境变量;从父工作空间继承;绝对不要硬编码密钥 |
| Datastore | 持久化键值存储 | 仅支持字符串和数字 |
| Storage | 文件存储 | 二进制文件、文档、大负载数据 |
| Locales | 多语言翻译文件( | 通过 |
| 内置事务性邮件功能 | 使用 |
Processes
Process
The basic unit of execution, in JavaScript () or Python ().
Processes may declare input parameters via JSON Schema (,
see ) and read them through .
Return structured JSON; for webhook-style responses return
.
index.jsmain.pyparametersSchema.jsonfcode-json-schemafcode.context.parameters{ status, headers, body }执行的基本单元,使用JavaScript()或Python()编写。Process可通过JSON Schema(,详见)声明输入参数,并通过读取参数。返回结构化JSON;若为Webhook风格响应,请返回。
index.jsmain.pyparametersSchema.jsonfcode-json-schemafcode.context.parameters{ status, headers, body }Modules
Module
Reusable libraries shared across processes — use them to avoid duplication,
encapsulate API clients/integrations, keep process code small, and support
versioning. See the module-naming gotcha above.
跨流程共享的可复用库——使用Module可避免代码重复、封装API客户端/集成、简化Process代码,并支持版本控制。请遵守上述Module命名的注意事项。
Execution context
Execution context
Each process runs isolated, with access to:
- Input parameters:
fcode.context.parameters - Environment variables: /
process.env.*(oros.getenv(...))fcode.env.* - Execution metadata:
fcode.execution.* - Request data (webhooks): request body/headers when applicable
每个Process运行在隔离环境中,可访问以下内容:
- 输入参数:
fcode.context.parameters - 环境变量:/
process.env.*(或os.getenv(...))fcode.env.* - 执行元数据:
fcode.execution.* - 请求数据(Webhook场景):适用时可获取请求体/请求头
Variables (configuration & secrets)
Variables(配置与密钥)
Store base URLs, timeouts, API keys, and tokens as variables (never hardcode).
holds team variables (); holds
local-only overrides. See the overwrite gotcha above.
variables.envKEY=VALUEvariables.local.envvariables.meta.jsonisSensitive********variables.envvariables.local.envfcode-cliWhen a secret's real value is needed for local runs, ask the user for it — or
have them put it in themselves if they prefer not to
share it. comes from the OAuth flow in the Factorial Code app
details page and is only needed locally (auto-populated remotely); procedure in
.
variables.local.envFACTORIAL_TOKENfcode-cliA team variable is also how a webhook is protected: the process names the
variable holding the token it expects, and callers send that value as
. Only the variable name is stored with the
process, so the token stays out of exports and out of committed files.
Authorization: Bearer <token>Read them at runtime via . To create/update/delete them
programmatically from a process, use the helper
(///) — scoped to your team, no API token needed. See
/ .
fcode.env.*fcode.variablessetgetlistdeletefcode-javascriptfcode-python将基础URL、超时时间、API密钥和令牌存储为变量(绝对不要硬编码)。存储团队变量(格式);存储本地专属覆盖值。请遵守上述覆盖文件的注意事项。
variables.envKEY=VALUEvariables.local.envvariables.meta.jsonisSensitivevariables.env********variables.local.envfcode-cli本地运行需要真实密钥值时,请向用户索取——或让用户自行将值放入(若用户不愿共享)。来自Factorial Code应用详情页的OAuth流程,仅本地运行时需要(云端会自动填充);操作流程详见。
variables.local.envFACTORIAL_TOKENfcode-cli团队变量也可用于保护Webhook:Process指定存储预期令牌的变量名称,调用方将该值作为发送。仅变量名称会与Process一起存储,因此令牌不会出现在导出内容和已提交文件中。
Authorization: Bearer <token>运行时可通过读取变量。如需从Process中以编程方式创建/更新/删除变量,请使用辅助工具(///)——作用域限于当前团队,无需API令牌。详情请见/。
fcode.env.*fcode.variablessetgetlistdeletefcode-javascriptfcode-pythonVariables are inherited from parent workspaces
变量从父工作空间继承
A workspace uses the variables defined in any of its parents
without redefining them, alongside processes and modules. Inheritance follows the
same rule those already use: the workspace first, then its direct parents
sorted by slug, capped at 5 — so it is not transitive (a grandparent's
variables don't reach a grandchild).
parentTeamSlugs- Don't re-create a parent's variables in a child. They already resolve
there. This is why a workspace carries only the values specific to that customer, while shared defaults and credentials stay in
deploy-{deployId}/prod-{appId}.base-app - Defining the same key in the child overrides the inherited one for that workspace — the child's value is what its executions see, and the parent's entry disappears from the child's list entirely (one entry per key, never two). Deleting the override brings the parent's value back.
- Inherited variables are read-only where they're inherited. Edit or delete
them in the workspace that owns them, or override them locally. In the web UI
they carry an inherited badge and offer Override here; the CLI and SDK
behaviours are in and
fcode-cli/fcode-javascript.fcode-python - Secrets inherit too, and their real values reach the sandbox. A process in
a child workspace reads a parent's secret at execution time. They stay masked
everywhere else (over GraphQL,
nullover REST,******in the CLI's inherited file), so process code is the only place a value is readable. Treat code in a child workspace as trusted with its parents' credentials.******** - Local runs get the placeholder, not the secret — put real values in
(see
variables.local.env).fcode-cli
工作空间会使用其中任意父工作空间定义的变量,无需重新定义,同时继承Process和Module。继承规则与已有的规则一致:优先使用当前工作空间的变量,然后按slug排序的直接父工作空间(最多5个)——因此继承不具有传递性(祖父工作空间的变量不会传递到孙工作空间)。
parentTeamSlugs- 不要在子工作空间中重新创建父工作空间的变量。这些变量已在子工作空间中生效。这也是工作空间仅存储特定客户专属值,而共享默认值和凭证保留在
deploy-{deployId}/prod-{appId}中的原因。base-app - 在子工作空间中定义相同键会覆盖继承的值——子工作空间的变量值会被其执行流程读取,父工作空间的对应条目会从子工作空间的列表中完全消失(每个键仅保留一个条目,绝不会出现两个)。删除覆盖值会恢复父工作空间的变量值。
- 继承的变量在继承空间中为只读。请在所属工作空间中编辑或删除这些变量,或在本地覆盖。Web UI中继承变量会带有继承标识,并提供“在此处覆盖”选项;CLI和SDK的行为详见和
fcode-cli/fcode-javascript。fcode-python - 密钥也会继承,且真实值会传递到沙箱。子工作空间中的Process在执行时会读取父工作空间的密钥。在其他所有场景中,密钥都会被屏蔽(GraphQL返回,REST返回
null,CLI继承文件中显示******),因此只有Process代码可以读取真实值。请将子工作空间中的代码视为可信任父工作空间凭证的代码。******** - 本地运行仅获取占位符,而非真实密钥——请将真实值放入(详见
variables.local.env)。fcode-cli
Schedules
Schedules
Run a process on a cron or one-off date/time. Manage schedules from process code
with the helper (/////
//) — same out-of-the-box auth as the other
helpers. See / .
fcode.schedulecreatelistgetupdatepauseresumedeletedeleteForProcessfcode-javascriptfcode-python按 cron 表达式或一次性日期/时间运行Process。可通过辅助工具(///////)从Process代码中管理调度——与其他辅助工具使用相同的开箱即用认证机制。详情请见/。
fcode.schedulecreatelistgetupdatepauseresumedeletedeleteForProcessfcode-javascriptfcode-pythonDatastore vs Storage
Datastore vs Storage
- Datastore — persistent key-value state across runs (last-run timestamps, cursors, dedup IDs, small caches). Strings/numbers only.
- Storage — files that don't belong in datastore (reports, exports, images, PDFs, data extracts).
- Datastore —— 跨运行的持久化键值状态(上次运行时间戳、游标、去重ID、小型缓存)。仅支持字符串/数字。
- Storage —— 不适合存储在Datastore中的文件(报告、导出文件、图片、PDF、数据提取文件)。
Sending email
发送邮件
Send email with the built-in ( in Python) —
pre-authenticated, no SMTP configuration. The mail server and credentials live in
the executor manager, never in your process. Each execution can send up to 3
emails by default. See / for usage.
fcode.sendMailfcode.send_mailfcode-javascriptfcode-python使用内置的(Python中为)发送邮件——已预认证,无需SMTP配置。邮件服务器和凭证由执行管理器维护,绝不会出现在您的Process中。默认每个执行流程最多可发送3封邮件。使用方法详见/。
fcode.sendMailfcode.send_mailfcode-javascriptfcode-pythonVersioning & aliases
版本控制与别名
Processes and modules can be versioned individually, and a workspace version
publishes one tag (e.g. ) on every process and module the team owns
at once — resources inherited through are never touched. Each
entity's outcome (created / skipped / failed) is recorded in the version's
manifest, so re-creating the same tag after a partial failure only publishes
what is still missing.
v1.0.0parentTeamSlugsWhen a workspace version is published, bare /
calls of workspace-owned modules are pinned to the
tag inside the published snapshots only — the working copy is never
modified, and imports that already carry a tag or alias are left untouched.
A workspace version also publishes every owned locale and pins bare
calls the same way, in code and in form schemas, so a release
ships with its translations frozen — see .
fcode.import("mod")fcode.import_module("mod")fcode.i18nfcode-i18nA version alias is a movable pointer to a version. The alias
always exists and points at the workspace's stable version. Webhooks, forms,
schedules, and module imports accept an alias wherever they accept a tag, so
moving to another version re-points the whole workspace in one
operation — rollout and rollback are a single alias change. Always pin
consumers (webhook URLs, form embeds) to ; how in and
.
stablestablestablefcode-clifcode-formsTwo consequences of that model:
- never affects consumers pinned to
fcode push. Pushing updates the current (unversioned) code; pinned consumers keep running the released version until the alias moves.stable - Deleting a workspace version cascades — every owned process/module version carrying the tag is deleted, together with the aliases, executions, and schedules referencing them.
Versions are published and aliases linked from the web UI (team settings →
Versions tab). The CLI equivalents ( /
) are documented in — don't create versions or move
unless explicitly asked.
fcode team:versions:*team:aliases:*fcode-clistableA version tag () is unrelated to — those are
process labels (used e.g. for MCP-tool exposure, see ).
v1.0.0metadata.jsontagsfcode-agentProcess和Module可单独进行版本控制,Workspace version会一次性为团队所有的每个Process和Module发布一个标签(如)——通过继承的资源绝不会被修改。每个实体的发布结果(创建/跳过/失败)会记录在版本的manifest中,因此部分失败后重新创建相同标签只会发布仍缺失的内容。
v1.0.0parentTeamSlugs发布Workspace version时,对工作空间所属Module的裸调用/会在发布快照中被固定到该标签仅在发布快照中——工作副本绝不会被修改,已带有标签或别名的导入操作不会被改动。Workspace version还会发布所有所属Locale,并以相同方式固定裸调用(包括代码和表单Schema),因此版本发布时会冻结对应的翻译——详见。
fcode.import("mod")fcode.import_module("mod")fcode.i18nfcode-i18nVersion alias是指向版本的可移动指针。别名始终存在,指向工作空间的稳定版本。Webhook、表单、调度和Module导入在接受标签的位置也接受别名,因此将移动到另一个版本即可一次性重新指向整个工作空间——版本发布与回滚仅需修改一次别名。请始终将消费者(Webhook URL、表单嵌入)固定到;操作方法详见和。
stablestablestablefcode-clifcode-forms该模型的两个结果:
- 绝不会影响固定到
fcode push的消费者。推送会更新当前(未版本化)的代码;固定的消费者会继续运行已发布的版本,直到别名被移动。stable - 删除Workspace version会级联删除——所有带有该标签的所属Process/Module版本,以及引用它们的别名、执行记录和调度都会被删除。
版本发布和别名关联可通过Web UI(团队设置→Versions标签页)完成。对应的CLI命令(/)详见——除非明确要求,否则不要创建版本或移动别名。
fcode team:versions:*team:aliases:*fcode-clistable**版本标签()**与中的无关——后者是Process的标签(例如用于MCP-tool曝光,详见)。
v1.0.0metadata.jsontagsfcode-agentDecision guidelines
决策指南
Module vs inline code
| Scenario | Recommendation |
|---|---|
| API client used by multiple processes | Create a module |
| Utility helpers used 2+ times | Create a module |
| One-off transformation / single-use logic | Keep inline |
Datastore vs Variables vs Storage
| Need | Use |
|---|---|
| Config that rarely changes; secrets/credentials | Variables |
| State that changes between runs; cached API responses | Datastore |
| Binary files / large exports | Storage |
Module vs 内联代码
| 场景 | 建议 |
|---|---|
| 被多个Process使用的API客户端 | 创建Module |
| 被使用2次及以上的工具函数 | 创建Module |
| 一次性转换/仅使用一次的逻辑 | 保留内联 |
Datastore vs Variables vs Storage
| 需求 | 使用方式 |
|---|---|
| 很少更改的配置;密钥/凭证 | Variables |
| 运行间变化的状态;缓存的API响应 | Datastore |
| 二进制文件 / 大型导出文件 | Storage |
Naming conventions
命名规范
| Resource | Convention | Example |
|---|---|---|
| Process slug | kebab-case | |
| Module slug | kebab-case | |
| Variables | SCREAMING_SNAKE_CASE | |
| JavaScript functions | camelCase | |
| Python functions | snake_case | |
| 资源 | 规范 | 示例 |
|---|---|---|
| Process slug | kebab-case | |
| Module slug | kebab-case | |
| Variables | SCREAMING_SNAKE_CASE | |
| JavaScript函数 | camelCase | |
| Python函数 | snake_case | |
Workspace structure (CLI)
工作空间结构(CLI)
A local workspace managed by the CLI (see ):
fcodefcode-cli📦 <workspace-name>
┣ 📂 dependencies # shared deps: package.json (JS) / requirements.txt (Py)
┣ 📂 i18n
┃ ┣ 📜 <locale>.yaml # translations this workspace owns (see fcode-i18n)
┃ ┗ 📜 <locale>.inherited.yaml # inherited translations (read-only, gitignored)
┣ 📂 modules
┃ ┗ 📂 <module-slug> # one folder per module
┃ ┗ 📜 <module-slug>.js # entry file named after the slug (NOT index.js)
┣ 📂 processes
┃ ┗ 📂 <process-slug> # one folder per process
┃ ┣ 📜 index.js # or main.py — the process entry file
┃ ┣ 📜 parametersSchema.json # input parameter schema (the form)
┃ ┣ 📜 parameters.json # default test parameters for `fcode run`
┃ ┣ 📜 metadata.json # name, description, tags, webhook/form settings + auth
┃ ┣ 📜 README.md
┃ ┗ 📜 package.json # optional process-scoped dependencies
┣ 📜 datastore.json
┣ 📜 team.json # team settings: inheritance, timezone, error handler, webhook auth
┣ 📜 variables.env # team variables this workspace owns (KEY=VALUE)
┣ 📜 variables.inherited.env # variables from parent workspaces (read-only, gitignored)
┣ 📜 variables.local.env # local overrides (not shared)
┣ 📜 variables.meta.json # per-variable isSensitive flags
┗ 📂 .fcodeProcesses and modules also carry subfolders (e.g.
) holding their published version snapshots — see the
versioning section above. holds only the inner
object (e.g. ).
versions/<tag>/versions/v1.0.0/dependencies/package.jsondependencies{ "axios": "^1.6.0" }metadata.jsonenabledauthModeappRolefcode pushauthMode: NONEwebhookAuthteam.jsonTEAMCUSTOMfcode-cli由 CLI管理的本地工作空间(详见):
fcodefcode-cli📦 <workspace-name>
┣ 📂 dependencies # 共享依赖:package.json(JS)/ requirements.txt(Py)
┣ 📂 i18n
┃ ┣ 📜 <locale>.yaml # 本工作空间所属的翻译文件(详见fcode-i18n)
┃ ┗ 📜 <locale>.inherited.yaml # 继承的翻译文件(只读,已加入git忽略)
┣ 📂 modules
┃ ┗ 📂 <module-slug> # 每个Module对应一个文件夹
┃ ┗ 📜 <module-slug>.js # 入口文件以slug命名(不可用index.js)
┣ 📂 processes
┃ ┗ 📂 <process-slug> # 每个Process对应一个文件夹
┃ ┣ 📜 index.js # 或main.py —— Process入口文件
┃ ┣ 📜 parametersSchema.json # 输入参数Schema(表单定义)
┃ ┣ 📜 parameters.json # `fcode run`命令使用的默认测试参数
┃ ┣ 📜 metadata.json # 名称、描述、标签、Webhook/表单设置及认证信息
┃ ┣ 📜 README.md
┃ ┗ 📜 package.json # 可选的Process级依赖
┣ 📜 datastore.json
┣ 📜 team.json # 团队设置:继承关系、时区、错误处理器、Webhook认证
┣ 📜 variables.env # 本工作空间所属的团队变量(KEY=VALUE格式)
┣ 📜 variables.inherited.env # 来自父工作空间的变量(只读,已加入git忽略)
┣ 📜 variables.local.env # 本地覆盖值(不共享)
┣ 📜 variables.meta.json # 每个变量的isSensitive标志
┗ 📂 .fcodeProcess和Module还包含子文件夹(例如),存放其发布版本的快照——详见上述版本控制部分。仅包含内部的对象(例如)。
versions/<tag>/versions/v1.0.0/dependencies/package.jsondependencies{ "axios": "^1.6.0" }metadata.jsonenabledauthModeappRolefcode pushauthMode: NONEteam.jsonwebhookAuthTEAMCUSTOMfcode-cliGeneral rules
通用规则
- Validate inputs early — check required parameters and types at the start.
- Handle errors explicitly; throw meaningful, actionable errors, and log every caught error with context (what operation, which inputs) before re-throwing.
- Use timeouts/retries for external calls; mind rate limits.
- Log generously through the shared module — level-gated logging via the
fcode-logsteam variable (defaultLOG_LEVEL). Log start/end, major decisions, and external calls atinfo, and detail (payloads, intermediate state) atinfo(gated off in production). Never log secrets. Usage indebug/fcode-javascript.fcode-python - Keep outputs structured (JSON that's easy to consume and debug).
- 尽早验证输入——在流程开始时检查必填参数和类型。
- 显式处理错误;抛出有意义、可操作的错误,并在重新抛出前记录每个捕获的错误及上下文(操作内容、输入参数)。
- 对外部调用使用超时/重试机制;注意速率限制。
- 通过共享的模块充分记录日志——通过团队变量
fcode-logs(默认LOG_LEVEL)控制日志级别。在info级别记录开始/结束、主要决策和外部调用,在info级别记录详细信息(负载、中间状态)(生产环境中会关闭debug级别)。绝对不要记录密钥。使用方法详见debug/fcode-javascript。fcode-python - 保持输出结构化(便于消费和调试的JSON格式)。",