@codemuniverse/codem-sandbox-cli
v0.1.12
Published
CodeM token based sandbox CLIs for Meegle and Lark knowledge access.
Readme
CodeM Sandbox CLI
Agent-facing CLIs that wrap CodeM sandbox proxy endpoints.
Both CLIs authenticate with the sandbox-injected CODEM_TOKEN and never ask the
agent for Meego or Lark app id, app secret, plugin token, or tenant token.
Install
npm i -g @codemuniverse/codem-sandbox-cli --registry=https://registry.npmmirror.comEnvironment
CODEM_TOKEN: required CodeM identity token.CODEM_BASE_URL: CodeM server origin. Defaults tohttps://codem.feishu.cn.CODEM_PROXY_BASE_URL: optional override for this CLI.CODEM_BASE_HTTP_URL: compatibility alias for the CodeM server URL.CODEM_DISPATCH_ID: optional task context for stricter Meegle write checks.AI_EVENT_TYPE: Meego AI event type forsandbox-meegle-cli. Values starting with80use AI node flow, values starting with82use status flow.--ai-event-typeoverrides this env var.CODEM_AI_ENTITY_ID: optional AI entity id. It is required by write commands if--ai-entity-idis not passed. The proxy forwards it to Meego operation OpenAPI requests asx-ai-entity-id; query commands do not send this header.CODEM_AI_ENTITY_STATUS: optional status forai-node done; defaults todone.
--base-url may be either an origin such as https://codem.feishu.cn or a
/goapi/codem prefix URL.
Meegle Commands
AI_EVENT_TYPE=8007 \
sandbox-meegle-cli workitem get \
--project-key proj \
--work-item-type story \
--work-item-id 123 \
--fields '["name","status"]'AI_EVENT_TYPE=8207 \
sandbox-meegle-cli workflow transition \
--project-key proj \
--work-item-type story \
--work-item-id 123 \
--ai-entity-id ai_entity_1 \
--field-json '{"field_key":"status","field_value":"done"}'sandbox-meegle-cli ai-node done \
--project-key proj \
--work-item-id 123 \
--state-key state_ai_current \
--ai-entity-id ai_entity_1UUID=$(sandbox-meegle-cli workitem get \
--project-key proj \
--work-item-type story \
--work-item-id 123 \
--fields '["files_field"]' \
--data-only | jq -r '.items[0].fields.files_field[0].uuid')
sandbox-meegle-cli attachment +download \
--project-key proj \
--work-item-type story \
--work-item-id 123 \
--uuid "$UUID" \
--output ./a.pdf \
--overwriteAll commands print JSON. Pass --data-only to print the proxy response data
field only.
Meegle Parameters
Common parameters:
--project-key: required Meego project key or space simple name.--dispatch-id/CODEM_DISPATCH_ID: optional task context. When present, the proxy additionally checks that the token, cluster, Meego project, and source work item match that dispatch. When omitted, writes are authorized by theCODEM_TOKENtenant/project/cluster scope plus the bound Meego space.--ai-event-type/AI_EVENT_TYPE: Meego AI event type. Prefix80means AI node flow; prefix82means status flow. Callers only pass the event type; CodeM chooses the server-side Meego credentials and headers.--ai-entity-id/CODEM_AI_ENTITY_ID: required for write commands (workflow transitionandai-node done). The proxy sends it asx-ai-entity-idon Meego operation OpenAPI requests.workitem getdoes not sendx-ai-entity-id.--state-key/--node-id: optional current-node/current-state override. ForAI_EVENT_TYPE=80*node flow, omit it to let the proxy use the existing auto-selectedcurrent_nodes[0].id; pass it when a work item has multiple current nodes and you need to choose the exact AI node. For82*status flow, it is the currentwork_item_status.state_key, not the target state.--node-uuid: optional AI node uuid for80*node flow, alternative to--state-key/--node-id.--transition-id: optional override forworkflow transitionwhenAI_EVENT_TYPEstarts with82. The proxy normally queries workflow detail withflow_type=1, finds theconnections[]record whosesource_state_keyequals the current state key, and uses that record'stransition_id. If supplied, it must be the next-state connection id as int64, not a state key such asRESOLVED.
Command-specific parameters:
workitem get: requires--work-item-typeand--work-item-id; optional--fields,--expand-json, and--ai-event-type.workflow transition: requires--work-item-type,--work-item-id,--ai-entity-id, and--ai-event-typeorAI_EVENT_TYPE. Prefix80runs AI node flow; prefix82runs status flow. For80*, the proxy uses the supplied--state-key/--node-idor--node-uuidwhen present; otherwise it keeps the existing auto behavior and uses the first node id fromcurrent_nodes. It then callsPOST /open_api/ai_node/editwithstatus=doneandPOST /open_api/ai_node/confirm. For82*, the proxy uses a supplied--transition-idfirst; if omitted, it queries currentstate_keyand workflow connections to resolvetransition_id, then calls Meego state transitionPOST /open_api/:project_key/workflow/:work_item_type_key/:work_item_id/node/state_change, then callsPUT /open_api/ai_entity/update(OAPIUpdateAiEntity) withproject_keyandupdate_ai_entity_param[0]carryingentity_id=<ai_entity_id>andstatus=done.ai-node done: requires--work-item-id,--ai-entity-id, and--state-key/--node-id(or--node-uuid). This is also the current AI node state key. Optional--statusdefaults todone.attachment +download: requires--project-key,--work-item-type,--work-item-id,--uuid/--file-uuid, and--output. Get theuuidfromworkitem get; the proxy rejects requests withoutuuid. Rich-text attachments are returned undermulti_texts, and attachment fields whose type ismulti_filealso include fileuuid. The proxy calls MeegoPOST /open_api/:project_key/work_item/:work_item_type_key/:work_item_id/file/downloadwith body{"uuid":"..."}and streams the binary response back to the CLI. The CLI writes to<output>.partialand atomically renames to--output. Pass--overwriteto replace an existing file.
workitem get always sends expand.need_multi_text=true to Meego OpenAPI from
the proxy, even when the caller omits --expand-json, so rich-text and attachment
references needed for downloads can be returned by Meego.
ai-node done calls Meego POST /open_api/ai_node/edit through the CodeM proxy
and sends this OpenAPI body shape:
{
"project_key": "proj",
"work_item_id": "123",
"state_key": "state_ai_current",
"status": "done"
}The CodeM proxy obtains Meego plugin credentials, plugin tokens, configured
headers, hosts, and configured Meego user_key server-side. The sandbox process
only supplies CODEM_TOKEN and operation parameters. sandbox-meegle-cli does
not accept or forward a caller-provided Meego user key; if the selected TCC block
has no user_key, the server reports the Meego proxy as unavailable.
Server-side Meego identity selection is hidden behind the proxy. Operation
commands add x-ai-entity-id; query commands do not.
Meegle Proxy Endpoints
POST /goapi/codem/proxy/openapi/work_item/detailPOST /goapi/codem/proxy/openapi/work_item/state_changePOST /goapi/codem/proxy/openapi/ai_node/donePOST /goapi/codem/proxy/openapi/attachment/download
Lark Knowledge Commands
sandbox-lark-cli follows the official lark-cli docs +... command shape where
the operation is equivalent. All Lark commands authenticate only with
CODEM_TOKEN; the server exchanges the configured Lark app id/secret for a
tenant access token and uses app identity to call Lark OpenAPI.
The document scope is always the knowledge list bound in the CodeM space for the
token's project. The agent cannot search or read tenant-wide documents. Summary
search calls Feishu Search v2 POST /open-apis/search/v2/doc_wiki/search and
then the proxy filters results back to the bound knowledge token/URL set. Content
search reads bound document raw text with app identity and returns keyword
snippets.
docs +fetch and docs +search-content resolve the CodeM-bound document and
read Feishu Docx raw_content; the returned document block is populated from
the CodeM binding plus resolved document id, without an extra live document
metadata lookup.
The CodeM project key is decoded server-side from CODEM_TOKEN; callers do not
pass --project-key for sandbox-lark-cli.
Lark Recommended Workflow
- Search the bound knowledge scope and get candidate documents. The response
returns
knowledge_keyatdata.items[].knowledge.knowledge_key.
sandbox-lark-cli docs +search \
--query design \
--page-size 20The summary result also includes highlighted title, highlighted summary,
document URL, and owner metadata. Pick the document whose summary looks relevant
and keep its knowledge_key.
- Search exact body snippets. Without
--knowledge-key, this scans all readable documents bound to the CodeM space. With--knowledge-key, it limits matching to the selected document. The response also carriesdata.items[].knowledge.knowledge_key, so agents can still fetch the selected document after reading snippets.
sandbox-lark-cli docs +search-content \
--query "rollback strategy" \
--page-size 20sandbox-lark-cli docs +search-content \
--query "rollback strategy" \
--knowledge-key kn_1234567890 \
--context-chars 160 \
--matches-per-document 3- Fetch the full text of one bound document using the
knowledge_keyreturned bydocs +searchordocs +search-content.
sandbox-lark-cli docs +fetch \
--knowledge-key kn_1234567890For agent workflows that only need text:
sandbox-lark-cli docs +fetch \
--knowledge-key kn_1234567890 \
--content-onlyLark Parameters
--query: required fordocs +searchanddocs +search-content.--page-size: maximum summary results or content matches. Summary search is capped by the server and Feishu Search v2 page size.--page-token: continuedocs +searchfrom the previous summary search response.--knowledge-key: required fordocs +fetch; optional fordocs +search-contentto limit full-text matching to one bound document.--context-chars: content-search context characters around each hit.--matches-per-document: maximum content-search hits per document.--content-only: fordocs +fetch, print only document plain text.--data-only: print only the proxydatafield.
Lark Proxy Endpoints
POST /goapi/codem/proxy/lark/knowledge/searchPOST /goapi/codem/proxy/lark/knowledge/readPOST /goapi/codem/proxy/lark/knowledge/fulltext_search
