Skip to content
Merged
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 packages/cli/src/agent-code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ add_filter('datamachine_code_remote_workspace_backend_should_handle', '__return_
$sandbox_workspace_adoptions = array();
if (function_exists('wp_get_ability')) {
$sandbox_adopt_callback = static function () use (&$sandbox_workspace_adoptions): void {
$sandbox_adopt_ability = wp_get_ability('datamachine/workspace-adopt');
$sandbox_adopt_ability = wp_get_ability('datamachine-code/workspace-adopt') ?: wp_get_ability('datamachine/workspace-adopt');
if (!$sandbox_adopt_ability || !method_exists($sandbox_adopt_ability, 'execute')) {
return;
}
Expand Down
1 change: 1 addition & 0 deletions scripts/agent-sandbox-code-smoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ async function main() {
assert.doesNotMatch(code, /AgentsAPIAIWP_Agent_Execution_Principal/, "sandbox chat should not collapse namespaced runtime principal references")
assert.match(code, /PermissionHelper::run_as_authenticated/, "sandbox chat should execute runtime abilities in an authenticated Data Machine context")
assert.match(code, /DataMachine\\Abilities\\PermissionHelper::run_as_authenticated/, "sandbox chat should emit a valid namespaced PermissionHelper class reference")
assert.match(code, /datamachine-code\/workspace-adopt/, "sandbox setup should use the canonical Data Machine Code workspace adopt ability")
assert.doesNotMatch(code, /PermissionHelper::run_as_authenticated\([^\)]*,\s*1\)/, "sandbox chat should not force a user-specific Data Machine capability check")
assert.doesNotMatch(code, /DataMachineAbilitiesPermissionHelper/, "sandbox chat should not collapse namespaced PermissionHelper references")
assert.doesNotMatch(code, /datamachine_agent_mode_sandbox/, "sandbox chat should not depend on Data Machine agent mode filters")
Expand Down
72 changes: 72 additions & 0 deletions scripts/recipe-workspace-vfs-materialization-smoke.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import assert from "node:assert/strict"
import { execFile } from "node:child_process"
import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises"
import { tmpdir } from "node:os"
import { join, resolve } from "node:path"
import { promisify } from "node:util"

const execFileAsync = promisify(execFile)
const root = resolve(import.meta.dirname, "..")
const workspace = await mkdtemp(join(tmpdir(), "wp-codebox-recipe-workspace-vfs-materialization-"))

try {
const seed = join(workspace, "seed")
const recipePath = join(workspace, "recipe.json")
const artifacts = join(workspace, "artifacts")
await mkdir(seed, { recursive: true })
await writeFile(join(seed, "plugin.php"), "<?php\n// before\n")
await writeFile(join(seed, "remove-me.txt"), "delete this\n")

await writeFile(recipePath, `${JSON.stringify({
schema: "wp-codebox/workspace-recipe/v1",
runtime: { wp: "7.0" },
inputs: {
workspaces: [
{
target: "/workspace/materialization-smoke",
sourceMode: "repo-backed",
seed: {
type: "directory",
source: "./seed",
slug: "materialization-smoke",
},
},
],
},
workflow: {
steps: [
{
command: "wordpress.run-php",
args: [
"code=" + [
"file_put_contents('/workspace/materialization-smoke/plugin.php', \"<?php\\n// after from playground\\n\");",
"file_put_contents('/workspace/materialization-smoke/generated.txt', \"created inside playground\\n\");",
"unlink('/workspace/materialization-smoke/remove-me.txt');",
"echo 'workspace mutated';",
].join(" "),
],
},
],
},
artifacts: { directory: artifacts },
}, null, 2)}\n`)

const { stdout } = await execFileAsync(process.execPath, ["packages/cli/dist/index.js", "recipe-run", "--recipe", recipePath, "--json"], { cwd: root, timeout: 120_000 })
const output = JSON.parse(stdout)
assert.equal(output.success, true, output.error?.message ?? "recipe-run failed")
assert.ok(output.artifacts?.directory, "recipe-run should return an artifact directory")

const changedFiles = JSON.parse(await readFile(join(output.artifacts.directory, "files", "changed-files.json"), "utf8"))
const changed = new Map(changedFiles.files.map((file: { relativePath: string }) => [file.relativePath, file]))
assert.equal(changed.get("generated.txt")?.status, "added")
assert.equal(changed.get("plugin.php")?.status, "modified")
assert.equal(changed.get("remove-me.txt")?.status, "deleted")

const patch = await readFile(join(output.artifacts.directory, "files", "patch.diff"), "utf8")
assert.match(patch, /diff --git a\/workspace\/materialization-smoke\/generated\.txt b\/workspace\/materialization-smoke\/generated\.txt/)
assert.match(patch, /\+created inside playground/)
assert.match(patch, /\+\/\/ after from playground/)
assert.match(patch, /deleted file mode 100644/)
} finally {
await rm(workspace, { recursive: true, force: true })
}
1 change: 1 addition & 0 deletions scripts/smoke-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export const smokeGroups = {
tsxSmoke("recipe-staged-files-smoke"),
tsxSmoke("recipe-dependency-overlay-smoke"),
tsxSmoke("recipe-workspace-seed-excludes-smoke"),
tsxSmoke("recipe-workspace-vfs-materialization-smoke"),
tsxSmoke("recipe-runtime-evidence-smoke"),
tsxSmoke("recipe-run-timeout-smoke"),
tsxSmoke("recipe-playground-boot-failure-smoke"),
Expand Down