Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion SKILL/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ v8-runner init
- Extension properties need synchronization: use `v8-runner extensions` or `extensions --name <SOURCE_SET>`.
- Infobase changes need to become Git-visible files: check `git status`, then run the relevant `v8-runner dump ...` command.
- Source files need conversion between Designer and EDT: use `v8-runner convert`; this is CLI-only and does not use the infobase.
- Existing `.cf` or `.cfe` artifacts need to be applied to an infobase: use `v8-runner load ...`.
- Existing `.cf` or `.cfe` artifacts need to be applied to an infobase: use `v8-runner load ...`. To create a missing extension, only Designer artifact loading is supported: `v8-runner load --path <artifact>.cfe --mode load --extension <NAME>`; it does not create schema/MCP objects or build extension sources.
- Release artifacts need to be exported or external artifacts published: use `v8-runner make ...` or the `artifacts` alias.
- Need a 1C UI session: use `v8-runner launch designer`, `launch thin`, `launch thick`, or `launch ordinary`.
- Need an observable local external EPF runtime gate: use `launch thin --execute <file.epf> --output <out> --stderr-output <stderr> --wait-for-exit --wait-timeout-ms <ms>`. This opt-in mode is limited to explicit `.epf` files, reports PID/exit-or-timeout/artifacts, treats timeout as a CLI failure after terminating the client group, and rejects raw or configured `/C`, `/Execute`, and `/Out` aliases; callers must inspect the reported exit code because non-zero EPF exit is observational rather than a CLI failure; plain launch remains asynchronous.
Expand Down
1 change: 1 addition & 0 deletions docs/CAPABILITIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ v8-runner load --path <FILE> [--mode <load|merge>] [--settings <FILE>] [--extens
- Поддерживает `.cf` и `.cfe`.
- Работает только для `format=DESIGNER` и `builder=DESIGNER`.
- `.cfe` требует `--extension`.
- Если probe сообщает, что расширение отсутствует, `load --path <artifact>.cfe --mode load --extension <NAME>` создаёт его только из Designer-артефакта: выполняет `/LoadCfg` и затем `/UpdateDBCfg` с `-Extension <NAME>`. Команда не создаёт schema/MCP-объекты и не запускает build исходников.
- `--mode merge` требует `--settings <FILE>`.
- `load --mode update` не поддержан; используйте `load` или `merge`.

Expand Down
70 changes: 70 additions & 0 deletions tests/cli_load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,76 @@ fn merge_cfe_json_success_requires_extension_and_settings() {
assert!(calls.contains("/UpdateDBCfg -Extension ExistingExt"));
}

#[test]
fn load_cfe_json_creates_missing_extension_from_artifact() {
let (_dir, config_path, _binary_path, base_path, calls_log) = setup_project();
fs::write(base_path.join("release.cfe"), "cfe").expect("artifact");

let output = v8_runner_command()
.args([
"--config",
&config_path.display().to_string(),
"--json-message",
"load",
"--path",
"release.cfe",
"--mode",
"load",
"--extension",
"NewExt",
])
.output()
.expect("run command");

assert!(output.status.success());
let payload: Value = serde_json::from_slice(&output.stdout).expect("json");
assert_eq!(payload["ok"], true);
assert_eq!(payload["command"], "load");
assert_eq!(payload["data"]["mode"], "load");
assert_eq!(payload["data"]["artifact_type"], "extension_cfe");
assert_eq!(payload["data"]["extension"], "NewExt");
assert_eq!(
payload["data"]["execution"]["payload"]["target_kind"],
"extension"
);
assert_eq!(
payload["data"]["execution"]["payload"]["compatibility_state"],
"not_supported"
);
assert_eq!(payload["data"]["execution"]["payload"]["applied"], true);
assert_eq!(
payload["data"]["execution"]["payload"]["update_db_cfg_ran"],
true
);

let calls = fs::read_to_string(calls_log).expect("calls");
let calls = calls.lines().collect::<Vec<_>>();
let probe = calls
.iter()
.position(|call| {
call.contains("/CompareCfg")
&& call.contains("ExtensionConfiguration")
&& call.contains("ExtensionDBConfiguration")
&& call.contains("-FirstName NewExt")
&& call.contains("-SecondName NewExt")
})
.expect("extension compatibility probe");
let load = calls
.iter()
.position(|call| {
call.contains("/LoadCfg") && call.contains("release.cfe -Extension NewExt")
})
.expect("load call with artifact and extension");
let update = calls
.iter()
.position(|call| call.contains("/UpdateDBCfg -Extension NewExt"))
.expect("update call");
assert!(
probe < load && load < update,
"extension probe must precede load, which must precede database update"
);
}

#[test]
fn load_update_mode_returns_validation_payload() {
let (_dir, config_path, _binary_path, base_path, _calls_log) = setup_project();
Expand Down