@zeroroot-ai/zerocool 0.3.0 → 0.3.1

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.
@@ -16,9 +16,9 @@
16
16
  * first run trades it for a persistent host key, and every later run re-registers
17
17
  * with that key (ADR-0045). A sandboxed run has neither. It authenticates with
18
18
  * the PER-DISPATCH capability grant gibson mints for this run and injects as
19
- * `GIBSON_CALLBACK_ENDPOINT` + `GIBSON_CALLBACK_TOKEN`. That grant carries exactly
20
- * the authority of this dispatch, so this process never reads a bootstrap token
21
- * and never touches a host key.
19
+ * `GIBSON_CALLBACK_ENDPOINT` + `GIBSON_CG_JWT`. That grant carries exactly the
20
+ * authority of this dispatch, so this process never reads a bootstrap token and
21
+ * never touches a host key.
22
22
  *
23
23
  * THE CALLBACKS ARE GRANT-AUTHENTICATED. This process drives `opencode run`
24
24
  * headless and passes the per-dispatch grant to the child (see
@@ -35,15 +35,23 @@
35
35
  *
36
36
  * Environment (injected by the sandbox launch):
37
37
  *
38
+ * These names are gibson's canonical dispatch contract — the constants in gibson
39
+ * `internal/engine/harness/sandboxed/agent.go` (envAgent*). This process conforms
40
+ * to them; it does not define its own.
41
+ *
38
42
  * GIBSON_CALLBACK_ENDPOINT per-dispatch harness callback dial target (required)
39
- * GIBSON_CALLBACK_TOKEN per-dispatch capability grant (required)
40
- * GIBSON_TASK_GOAL the task to pursue (required)
43
+ * GIBSON_CG_JWT per-dispatch capability grant (CG-JWT) (required)
44
+ * GIBSON_AGENT_TASK_B64 base64 protojson gibson.types.v1.Task (required)
45
+ * GIBSON_MODEL provider/model resolved for the tenant at dispatch
41
46
  * GIBSON_CALLBACK_INSECURE "1" to dial the callback listener without TLS (kind)
42
- * GIBSON_MISSION_RUN_ID / GIBSON_AGENT_RUN_ID / GIBSON_TRACE_ID provenance
47
+ * GIBSON_MISSION_ID / GIBSON_MISSION_RUN_ID / GIBSON_AGENT_RUN_ID provenance
43
48
  * ZEROCOOL_WORKSPACE working directory (defaults to the cwd)
44
- * ZEROCOOL_MODEL provider/model for opencode
45
49
  * GIBSON_OPENCODE_SESSION_ID continue an earlier opencode session
46
50
  * GIBSON_TIMEOUT_MS hard deadline for the run, in ms
51
+ *
52
+ * The child `opencode run` still receives the grant as GIBSON_CALLBACK_TOKEN via
53
+ * {@link dispatchChildEnv} — that is the opencode plugin's own contract, fed from
54
+ * the GIBSON_CG_JWT this process reads.
47
55
  */
48
56
  import type { AgentOutcome } from "@zeroroot-ai/sdk";
49
57
  import { runOpencode } from "./opencode-run.js";
@@ -86,6 +94,13 @@ export interface DispatchContext extends CallbackGrant {
86
94
  * same environment.
87
95
  */
88
96
  export declare function dispatchChildEnv(g: CallbackGrant): NodeJS.ProcessEnv;
97
+ /**
98
+ * Decode the base64 protojson `gibson.types.v1.Task` the sandbox launch injects
99
+ * as `GIBSON_AGENT_TASK_B64` (gibson agent.go `envAgentTaskB64`) and return its
100
+ * goal. gibson sends the full typed Task, not a plain goal string, so decode it
101
+ * here rather than run opencode against an empty or malformed prompt.
102
+ */
103
+ export declare function decodeTaskGoal(taskB64: string | undefined): string;
89
104
  /**
90
105
  * Read one sandboxed dispatch's context from the environment.
91
106
  *
package/dist/dispatch.js CHANGED
@@ -19,6 +19,32 @@ export function dispatchChildEnv(g) {
19
19
  ...(g.traceId ? { GIBSON_TRACE_ID: g.traceId } : {}),
20
20
  };
21
21
  }
22
+ /**
23
+ * Decode the base64 protojson `gibson.types.v1.Task` the sandbox launch injects
24
+ * as `GIBSON_AGENT_TASK_B64` (gibson agent.go `envAgentTaskB64`) and return its
25
+ * goal. gibson sends the full typed Task, not a plain goal string, so decode it
26
+ * here rather than run opencode against an empty or malformed prompt.
27
+ */
28
+ export function decodeTaskGoal(taskB64) {
29
+ if (!taskB64) {
30
+ throw new Error("GIBSON_AGENT_TASK_B64 is not set. The sandbox launch injects the task to pursue as the " +
31
+ "base64 protojson of a gibson.types.v1.Task; without it there is nothing to run.");
32
+ }
33
+ let task;
34
+ try {
35
+ task = JSON.parse(Buffer.from(taskB64, "base64").toString("utf8"));
36
+ }
37
+ catch (e) {
38
+ throw new Error("GIBSON_AGENT_TASK_B64 is not valid base64 protojson of a gibson.types.v1.Task: " +
39
+ (e instanceof Error ? e.message : String(e)));
40
+ }
41
+ const goal = typeof task.goal === "string" ? task.goal.trim() : "";
42
+ if (!goal) {
43
+ throw new Error("GIBSON_AGENT_TASK_B64 decoded to a Task with no goal. Running opencode against an empty " +
44
+ "prompt would report whatever it says back as a mission result.");
45
+ }
46
+ return goal;
47
+ }
22
48
  /**
23
49
  * Read one sandboxed dispatch's context from the environment.
24
50
  *
@@ -34,22 +60,18 @@ export function dispatchChildEnv(g) {
34
60
  */
35
61
  export function readDispatchContext(env, opts = {}) {
36
62
  const endpoint = env.GIBSON_CALLBACK_ENDPOINT;
37
- const token = env.GIBSON_CALLBACK_TOKEN;
63
+ const token = env.GIBSON_CG_JWT;
38
64
  if (!endpoint) {
39
65
  throw new Error("GIBSON_CALLBACK_ENDPOINT is not set. A sandboxed dispatched run is authenticated by " +
40
66
  "the per-dispatch grant the sandbox launch injects, not by a bootstrap token — the " +
41
- "launch must supply the callback endpoint and token.");
67
+ "launch must supply the callback endpoint and the grant.");
42
68
  }
43
69
  if (!token) {
44
- throw new Error("GIBSON_CALLBACK_ENDPOINT is set but GIBSON_CALLBACK_TOKEN is not. The callbacks would " +
45
- "have no grant to authenticate with; a sandboxed run must not fall back to any other " +
46
- "identity, so this fails instead.");
47
- }
48
- const goal = env.GIBSON_TASK_GOAL?.trim();
49
- if (!goal) {
50
- throw new Error("GIBSON_TASK_GOAL is empty. The sandbox launch injects the task to pursue; running " +
51
- "opencode against an empty prompt would report whatever it says back as a mission result.");
70
+ throw new Error("GIBSON_CALLBACK_ENDPOINT is set but GIBSON_CG_JWT is not. The callbacks would have no " +
71
+ "grant to authenticate with; a sandboxed run must not fall back to any other identity, " +
72
+ "so this fails instead.");
52
73
  }
74
+ const goal = decodeTaskGoal(env.GIBSON_AGENT_TASK_B64);
53
75
  const timeoutRaw = env.GIBSON_TIMEOUT_MS ? Number(env.GIBSON_TIMEOUT_MS) : 0;
54
76
  return {
55
77
  callbackEndpoint: endpoint,
@@ -60,7 +82,7 @@ export function readDispatchContext(env, opts = {}) {
60
82
  traceId: env.GIBSON_TRACE_ID ?? "",
61
83
  goal,
62
84
  workspace: env.ZEROCOOL_WORKSPACE ?? opts.cwd ?? process.cwd(),
63
- ...(env.ZEROCOOL_MODEL ? { model: env.ZEROCOOL_MODEL } : {}),
85
+ ...(env.GIBSON_MODEL ? { model: env.GIBSON_MODEL } : {}),
64
86
  ...(env.GIBSON_OPENCODE_SESSION_ID ? { sessionId: env.GIBSON_OPENCODE_SESSION_ID } : {}),
65
87
  timeoutMs: Number.isFinite(timeoutRaw) && timeoutRaw > 0 ? timeoutRaw : 0,
66
88
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeroroot-ai/zerocool",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "opencode plugin: Gibson platform integration (zerocool). Zero-config LLM, tools, findings, knowledge, delegate/missions.",
5
5
  "license": "MIT",
6
6
  "repository": {