@kybernesis/create 0.5.1 → 0.6.0
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.
- package/dist/cli.js +2 -0
- package/dist/doctor.js +25 -0
- package/dist/init.d.ts +9 -0
- package/dist/init.js +15 -1
- package/dist/templates.d.ts +1 -1
- package/dist/templates.js +31 -4
- package/package.json +1 -1
- package/skills/fde-engagement/references/playbook.md +88 -1
package/dist/cli.js
CHANGED
|
@@ -22,6 +22,7 @@ function initOptions(rest) {
|
|
|
22
22
|
const subs = flag(rest, 'subagents');
|
|
23
23
|
return {
|
|
24
24
|
engineer: rest.includes('--engineer'),
|
|
25
|
+
studio: rest.includes('--studio'),
|
|
25
26
|
channel: flag(rest, "channel"),
|
|
26
27
|
host: flag(rest, "host"),
|
|
27
28
|
subagents: subs === undefined ? undefined : subs.split(',').map((s) => s.trim()).filter(Boolean),
|
|
@@ -59,6 +60,7 @@ ${bold("kyb")} — Kybernesis agent scaffolder & FDE toolkit
|
|
|
59
60
|
--host=<kind> ${dim("vercel|exe (default: vercel)")}
|
|
60
61
|
--subagents=a,b ${dim("department subagents (default: none)")}
|
|
61
62
|
--engineer ${dim("add the engineer layer: workshop sandbox + vision dev loop")}
|
|
63
|
+
--studio ${dim("wire for KYBER Studio: local execution + management routes")}
|
|
62
64
|
--yes ${dim("no prompts; take flags and defaults")}
|
|
63
65
|
${bold("kyb doctor")} preflight checks (keys, issuer, envs, discovery)
|
|
64
66
|
${bold("kyb skills")} install/refresh the FDE skill suite for Claude Code
|
package/dist/doctor.js
CHANGED
|
@@ -238,6 +238,31 @@ export async function doctor() {
|
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
|
+
// ── KYBER Studio wiring ────────────────────────────────────────────────
|
|
242
|
+
const hasLocal = existsSync(join(cwd, "agent/tools/local_shell.ts"));
|
|
243
|
+
const hasManage = existsSync(join(cwd, "agent/channels/kyb.ts"));
|
|
244
|
+
if (hasLocal) {
|
|
245
|
+
// Without the relay secret the tools compile, appear in the tool list, and
|
|
246
|
+
// fail at the moment the user asks for something — the worst time to learn
|
|
247
|
+
// a deployment is incomplete.
|
|
248
|
+
if (process.env.LOCAL_EXEC_AGENT_SECRET) {
|
|
249
|
+
add("pass", "local execution is configured (LOCAL_EXEC_AGENT_SECRET set)");
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
add("fail", "local execution has no LOCAL_EXEC_AGENT_SECRET", "the local_* tools will be offered to the model and fail on first use; set the shared secret the control-plane relay expects");
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (hasManage) {
|
|
256
|
+
// manage authorizes with the caller's control-plane grant, so it needs to
|
|
257
|
+
// know which agent it IS before it can check one.
|
|
258
|
+
if (process.env.KYBERNESIS_AGENT) {
|
|
259
|
+
add("pass", "management routes can resolve this agent's grants");
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
add("fail", "management routes have no KYBERNESIS_AGENT", "KYBER Studio cannot install or write routines here: the agent cannot check a grant for a name it does not know");
|
|
263
|
+
}
|
|
264
|
+
add("warn", "management routes need a writable working copy", "installing edits this repo and rebuilds; on a read-only serverless bundle the routes refuse. Set restartCommand in agent/channels/kyb.ts or an install will not take effect");
|
|
265
|
+
}
|
|
241
266
|
// ── engineer subagent (build capability scoped to a subagent) ──────────
|
|
242
267
|
const builderDir = join(cwd, "agent/subagents/builder");
|
|
243
268
|
if (existsSync(builderDir)) {
|
package/dist/init.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { type ChannelKind, type HostKind } from "./templates.js";
|
|
2
2
|
export interface InitOptions {
|
|
3
3
|
engineer?: boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Wire this agent for KYBER Studio: local execution on the user's own machine,
|
|
6
|
+
* and management routes so Studio can install capabilities and write routines.
|
|
7
|
+
*
|
|
8
|
+
* Off by default. Both let a client reach further than chat does — one onto
|
|
9
|
+
* the user's laptop, one into the agent's own repository — so they are a
|
|
10
|
+
* deliberate choice rather than something an engagement gets by accident.
|
|
11
|
+
*/
|
|
12
|
+
studio?: boolean;
|
|
4
13
|
/** Chat surface. Default "none" — add later with `kyb add channel`. */
|
|
5
14
|
channel?: ChannelKind;
|
|
6
15
|
/** Where the agent runs. Default "vercel". */
|
package/dist/init.js
CHANGED
|
@@ -17,6 +17,7 @@ const ENGINEER_ITEMS_VERCEL = ["connection/vercel"];
|
|
|
17
17
|
const DEFAULT_MODEL = "anthropic/claude-sonnet-5";
|
|
18
18
|
export async function init(rawName, options = {}) {
|
|
19
19
|
const engineer = options.engineer === true;
|
|
20
|
+
const studio = options.studio === true;
|
|
20
21
|
const nonInteractive = options.yes === true;
|
|
21
22
|
const name = slug(rawName ?? (await ask("Agent name (kebab-case)?", "acme-agent")));
|
|
22
23
|
if (!name) {
|
|
@@ -70,6 +71,18 @@ export async function init(rawName, options = {}) {
|
|
|
70
71
|
for (const item of plan.registryItems) {
|
|
71
72
|
run("npx", ["eve", "add", item, "--overwrite"], { cwd: dir, allowFail: true });
|
|
72
73
|
}
|
|
74
|
+
if (studio) {
|
|
75
|
+
// Two separate items on purpose: `local` lets the agent act on the USER'S
|
|
76
|
+
// machine (consent per effect, granted on the desktop); `manage` lets a
|
|
77
|
+
// client change THIS AGENT — its dependencies and its source. Different
|
|
78
|
+
// blast radius, so an agent can have one without the other.
|
|
79
|
+
console.log(bold("\n2b2 KYBER Studio: local execution + management routes …"));
|
|
80
|
+
for (const item of ["local", "manage"]) {
|
|
81
|
+
const ok = run("npx", ["eve", "add", item, "--overwrite"], { cwd: dir, allowFail: true });
|
|
82
|
+
if (!ok)
|
|
83
|
+
console.log(yellow(` ! ${item} did not install cleanly — re-run: npx eve add ${item}`));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
73
86
|
const engPlan = engineer ? engineerPlan(host, DEFAULT_MODEL) : null;
|
|
74
87
|
if (engPlan) {
|
|
75
88
|
console.log(bold("\n2c Engineer subagent: workshop sandbox + vision dev loop …"));
|
|
@@ -131,7 +144,7 @@ export async function init(rawName, options = {}) {
|
|
|
131
144
|
}
|
|
132
145
|
}
|
|
133
146
|
console.log(bold("\n5/6 Env template + hermetic eval script …"));
|
|
134
|
-
writeFileSync(join(dir, ".env.example"), envExample(name, depts, issuer, plan.env));
|
|
147
|
+
writeFileSync(join(dir, ".env.example"), envExample(name, depts, issuer, plan.env, host, DEFAULT_MODEL));
|
|
135
148
|
const pkgPath = join(dir, "package.json");
|
|
136
149
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
137
150
|
pkg.scripts = { ...pkg.scripts, eval: evalScript(name, depts) };
|
|
@@ -148,6 +161,7 @@ export async function init(rawName, options = {}) {
|
|
|
148
161
|
"self-testing (evals)",
|
|
149
162
|
channel === "none" ? null : `${channel} channel`,
|
|
150
163
|
host === "exe" ? "exe.dev host" : null,
|
|
164
|
+
studio ? "KYBER Studio (local execution + management routes)" : null,
|
|
151
165
|
engineer ? "engineer subagent (workshop + vision loop)" : null,
|
|
152
166
|
depts.length ? `${depts.length} dept subagent(s)` : null,
|
|
153
167
|
].filter(Boolean);
|
package/dist/templates.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare function subagentInstructionsMd(dept: string): string;
|
|
|
7
7
|
export declare function subagentArcanaTs(dept: string): string;
|
|
8
8
|
export declare function rootArcanaTs(): string;
|
|
9
9
|
export declare function evalFileTs(displayName: string, depts: string[]): string;
|
|
10
|
-
export declare function envExample(name: string, depts: string[], issuer: string, channelEnv?: string[]): string;
|
|
10
|
+
export declare function envExample(name: string, depts: string[], issuer: string, channelEnv?: string[], host?: "vercel" | "exe", model?: string): string;
|
|
11
11
|
export declare function evalScript(name: string, depts: string[]): string;
|
|
12
12
|
export type ChannelKind = "none" | "slack" | "imessage" | "telegram" | "discord" | "web";
|
|
13
13
|
export declare const CHANNEL_KINDS: ChannelKind[];
|
package/dist/templates.js
CHANGED
|
@@ -120,22 +120,46 @@ export default kybernesisBaseline({
|
|
|
120
120
|
${depts.length ? ` routing: [\n${routing}\n ],\n` : ""}});
|
|
121
121
|
`;
|
|
122
122
|
}
|
|
123
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Env every self-hosted agent needs and cannot infer.
|
|
125
|
+
*
|
|
126
|
+
* Both of these have bitten a real deployment. EXE_MODEL must match the LLM
|
|
127
|
+
* integration actually attached — a ChatGPT subscription serves OpenAI models,
|
|
128
|
+
* so an Anthropic code default fails against it. EXE_VM_NAME has no default at
|
|
129
|
+
* all by design: guessing a host would hand a user a working link into another
|
|
130
|
+
* agent's machine.
|
|
131
|
+
*/
|
|
132
|
+
function exeEnvBlock(name, model) {
|
|
133
|
+
return `# Self-hosted host + model (@kybernesis/exe)
|
|
134
|
+
# EXE_MODEL must match the LLM integration you attached to the VM. A ChatGPT
|
|
135
|
+
# subscription serves OpenAI models; the code default will fail against one.
|
|
136
|
+
# Set it explicitly rather than relying on ${model}.
|
|
137
|
+
EXE_MODEL="${model}"
|
|
138
|
+
# Preview URLs are built from this. There is no default on purpose.
|
|
139
|
+
EXE_VM_NAME="${name}"
|
|
140
|
+
|
|
141
|
+
`;
|
|
142
|
+
}
|
|
143
|
+
export function envExample(name, depts, issuer, channelEnv = [], host = "vercel", model = "") {
|
|
124
144
|
const deptVars = depts
|
|
125
145
|
.map((d) => {
|
|
126
146
|
const upper = d.toUpperCase().replace(/[^A-Z0-9]+/g, "_");
|
|
127
147
|
return `# ARCANA_${upper}_API_KEY="kb_..."\n# ARCANA_${upper}_WORKSPACE="${name}-${d}"`;
|
|
128
148
|
})
|
|
129
149
|
.join("\n");
|
|
150
|
+
const header = host === "exe"
|
|
151
|
+
? `# Real values live in .env.local ON THE HOST. \`eve start\` does NOT read it the
|
|
152
|
+
# way \`eve dev\` does — scripts/eve-server.sh exports it into the process.`
|
|
153
|
+
: `# Real values belong in Vercel envs (prod/preview Sensitive); \`eve deploy\`
|
|
154
|
+
# overwrites .env.local from the development environment on every deploy.`;
|
|
130
155
|
return `# ── Kybernesis agent environment ─────────────────────────────────────
|
|
131
|
-
|
|
132
|
-
# overwrites .env.local from the development environment on every deploy.
|
|
156
|
+
${header}
|
|
133
157
|
|
|
134
158
|
# Control-plane governance (@kybernesis/enterprise)
|
|
135
159
|
KYBERNESIS_ISSUER="${issuer}"
|
|
136
160
|
KYBERNESIS_AGENT="${name}"
|
|
137
161
|
|
|
138
|
-
${channelEnv.length ? `# Channel\n${channelEnv.join("\n")}\n\n` : ""}# Arcana memory (@kybernesis/arcana) — one workspace + scoped kb_ key per brain
|
|
162
|
+
${host === "exe" ? exeEnvBlock(name, model) : ""}${channelEnv.length ? `# Channel\n${channelEnv.join("\n")}\n\n` : ""}# Arcana memory (@kybernesis/arcana) — one workspace + scoped kb_ key per brain
|
|
139
163
|
# ARCANA_API_KEY="kb_..."
|
|
140
164
|
# ARCANA_COMPANY_WORKSPACE="${name}-company"
|
|
141
165
|
# ARCANA_DM_WORKSPACE="${name}-company"
|
|
@@ -360,8 +384,11 @@ export default defineSandbox({
|
|
|
360
384
|
revalidationKey: () => "kybernesis-workshop-v5-docker",
|
|
361
385
|
async bootstrap({ use }) {
|
|
362
386
|
const sandbox = await use();
|
|
387
|
+
// Base image is Debian-family; refresh indexes before installing browser deps.
|
|
363
388
|
await sandbox.run({ command: "apt-get update" });
|
|
364
389
|
await sandbox.run({ command: "npm install -g pnpm" });
|
|
390
|
+
// Explicit package.json rather than \`npm init -y\`: init derives the name from
|
|
391
|
+
// the directory, and npm rejects names starting with a dot (".shot").
|
|
365
392
|
await sandbox.run({
|
|
366
393
|
command:
|
|
367
394
|
"mkdir -p /workspace/.shot && cd /workspace/.shot && echo '{\\"name\\":\\"kyb-shot\\",\\"private\\":true}' > package.json && npm install playwright",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kybernesis/create",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "The Kybernesis agent scaffolder and FDE toolkit: one command to a governed, remembering, multiplayer, self-testing eve agent — plus doctor and upgrade.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -44,6 +44,9 @@ npm create @kybernesis acme-atlas -- --engineer
|
|
|
44
44
|
# ChatGPT/LLM subscription paying for inference. See section 11:
|
|
45
45
|
npm create @kybernesis acme-atlas -- --host=exe --engineer
|
|
46
46
|
|
|
47
|
+
# …or, when the client wants the desktop app (KYBER Studio) — see section 12:
|
|
48
|
+
npm create @kybernesis acme-atlas -- --studio
|
|
49
|
+
|
|
47
50
|
# 3. (Optional, for repeated use) put `kyb` on the PATH for the whole engagement:
|
|
48
51
|
npm install -g @kybernesis/create
|
|
49
52
|
```
|
|
@@ -1990,7 +1993,91 @@ Nothing here can be borrowed from another agent or another account.
|
|
|
1990
1993
|
against the client's `-eval` workspace, and a live turn on the real surface —
|
|
1991
1994
|
sent from the client's own device, not yours.
|
|
1992
1995
|
|
|
1993
|
-
## 12.
|
|
1996
|
+
## 12. KYBER Studio — the desktop surface
|
|
1997
|
+
|
|
1998
|
+
Slack and iMessage reach an agent where the client already works. KYBER Studio
|
|
1999
|
+
is the third door: a desktop app for people who do not live in a chat tool, and
|
|
2000
|
+
the only surface where an agent can work on the user's own files.
|
|
2001
|
+
|
|
2002
|
+
Reach for it when the client says any of: *"not everyone here uses Slack"*,
|
|
2003
|
+
*"I want it on my laptop"*, *"can it look at our repo"*, or when the pilot
|
|
2004
|
+
involves someone technical who will hand the agent real work.
|
|
2005
|
+
|
|
2006
|
+
### 12.1 What it is
|
|
2007
|
+
|
|
2008
|
+
- **The same agent.** Studio does not run anything. It talks to the agent you
|
|
2009
|
+
deployed — same memory, same tools, same subagents. Nothing to deploy twice.
|
|
2010
|
+
- **Governed by the same grants.** Sign-in is control-plane device flow, so
|
|
2011
|
+
desktop access is the grant you already manage. Revoke it and the desktop goes
|
|
2012
|
+
with it.
|
|
2013
|
+
- **Optionally hands and eyes.** With `@kybernesis/local` the agent can search,
|
|
2014
|
+
read, edit, write, and run commands on the user's machine, with consent.
|
|
2015
|
+
- **Optionally self-modifying.** With `@kybernesis/manage` the client can
|
|
2016
|
+
install capabilities and write routines from the app instead of asking you.
|
|
2017
|
+
|
|
2018
|
+
### 12.2 The two packages, and why they are separate
|
|
2019
|
+
|
|
2020
|
+
| | What it lets happen | Installed on |
|
|
2021
|
+
| --- | --- | --- |
|
|
2022
|
+
| `@kybernesis/local` | The agent acts on the USER's machine | the agent |
|
|
2023
|
+
| `@kybernesis/manage` | A client changes THE AGENT — deps and source | the agent |
|
|
2024
|
+
|
|
2025
|
+
Different blast radius, so they are separate items an engagement chooses
|
|
2026
|
+
independently. A reporting agent might want `local` and never `manage`. Neither
|
|
2027
|
+
is installed by default, because both let a client reach further than chat does.
|
|
2028
|
+
|
|
2029
|
+
```bash
|
|
2030
|
+
kyb init acme-agent --host=exe --studio # both, at scaffold time
|
|
2031
|
+
npx eve add local # or either one, later
|
|
2032
|
+
npx eve add manage
|
|
2033
|
+
```
|
|
2034
|
+
|
|
2035
|
+
`kyb doctor` checks both: the relay secret for local, and `KYBERNESIS_AGENT` for
|
|
2036
|
+
manage, since it cannot check a grant for a name it does not know.
|
|
2037
|
+
|
|
2038
|
+
### 12.3 Prerequisites, in order
|
|
2039
|
+
|
|
2040
|
+
1. **The agent is registered in the control plane** and the pilot users are
|
|
2041
|
+
granted. Studio lists exactly what a user has a grant for — an agent that is
|
|
2042
|
+
registered but ungranted is invisible, which is the correct behaviour and a
|
|
2043
|
+
confusing one if you forget you did it.
|
|
2044
|
+
2. **The agent has a URL on file.** Studio reads `/api/me/agents`; an agent with
|
|
2045
|
+
no deployment URL appears as unreachable rather than silently missing.
|
|
2046
|
+
3. **For `manage`: a writable working copy.** Installing edits the repo and
|
|
2047
|
+
rebuilds, so it works on a VM and refuses on a read-only serverless bundle,
|
|
2048
|
+
with that reason. Set `restartCommand` in `agent/channels/kyb.ts` or an
|
|
2049
|
+
install completes without taking effect.
|
|
2050
|
+
4. **For `local`: the relay secret** (`LOCAL_EXEC_AGENT_SECRET`) matching the
|
|
2051
|
+
control plane.
|
|
2052
|
+
|
|
2053
|
+
### 12.4 What consent looks like for the user
|
|
2054
|
+
|
|
2055
|
+
Studio asks per **effect** — run a command, read a file, write a file, list a
|
|
2056
|
+
directory — not per tool, and not per turn. Approving `read-file` once covers
|
|
2057
|
+
every tool that reads a file out, which is why adding a tool later cannot dodge
|
|
2058
|
+
a decision the user already made.
|
|
2059
|
+
|
|
2060
|
+
The default is ask. A working folder can be set, but it is a starting directory
|
|
2061
|
+
rather than a fence: permission to act on the machine is granted once, and the
|
|
2062
|
+
agent may work wherever it is asked to. Whether it builds in its own sandbox or
|
|
2063
|
+
on the user's files is decided by the ask, not by a mode — the same way a
|
|
2064
|
+
colleague knows "build me a demo" from "look at my repo".
|
|
2065
|
+
|
|
2066
|
+
### 12.5 State this plainly to the client
|
|
2067
|
+
|
|
2068
|
+
- **Local execution is not yet a governed capability.** The agent authenticates
|
|
2069
|
+
to the relay with a shared secret, so anyone holding it can reach a connected
|
|
2070
|
+
desktop in that org. It must become its own revocable grant, separate from
|
|
2071
|
+
"may talk to this agent". Do not install `local` at a client who would treat
|
|
2072
|
+
that as a surprise.
|
|
2073
|
+
- **Reading a file sends it to the model.** Execution is local; the reasoning is
|
|
2074
|
+
not. Fine for most work, and a conversation to have before a Studio points at
|
|
2075
|
+
a regulated repository.
|
|
2076
|
+
- **Management routes let a client change the agent.** That is the point, and it
|
|
2077
|
+
means the repository is no longer only yours. Agree who reviews what Studio
|
|
2078
|
+
writes — routines land as source files, so a normal review works.
|
|
2079
|
+
|
|
2080
|
+
## 13. Known gaps — state these plainly, do not sell around them
|
|
1994
2081
|
|
|
1995
2082
|
Being straight about these is a feature. Clients have met vendors who were not.
|
|
1996
2083
|
|