@kybernesis/create 0.15.8 → 0.16.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/doctor.js +14 -0
- package/dist/init.d.ts +6 -0
- package/dist/init.js +49 -1
- package/package.json +2 -2
- package/skills/self-hosting/SKILL.md +25 -0
package/dist/doctor.js
CHANGED
|
@@ -380,6 +380,20 @@ export async function doctor() {
|
|
|
380
380
|
add("warn", "@kybernesis/dispatch installed but no edges or dispatch channel found", "see the connect-agents skill");
|
|
381
381
|
}
|
|
382
382
|
}
|
|
383
|
+
// ── .agent identity (ARP) ──────────────────────────────────────────────
|
|
384
|
+
// The owner connects the agent from the ARP console; the only thing that
|
|
385
|
+
// has to be true in this repo is that deliveries get in.
|
|
386
|
+
if (deps["@kybernesis/identity"]) {
|
|
387
|
+
if (!existsSync(join(cwd, "agent/channels/arp.ts")))
|
|
388
|
+
add("warn", "identity: agent/channels/arp.ts missing", "npx eve add @kybernesis/identity (serves /eve/v1/arp for Connect your agent)");
|
|
389
|
+
if (eveChannelSrc && !eveChannelSrc.includes("arpAuth("))
|
|
390
|
+
add("fail", "identity: eve channel has no arpAuth()", "add arpAuth() to the channel's auth list — without it every delivery from a paired agent is a 401");
|
|
391
|
+
else if (eveChannelSrc)
|
|
392
|
+
add("pass", "identity: eve channel accepts ARP deliveries (arpAuth)");
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
add("warn", "no .agent identity add-on", "npx eve add @kybernesis/identity — lets the owner connect this agent to a .agent name from the console");
|
|
396
|
+
}
|
|
383
397
|
// ── self-hosted agents (host !== Vercel) ───────────────────────────────
|
|
384
398
|
// Every check here cost a real debugging session on the first exe.dev
|
|
385
399
|
// deployment. None of them are theoretical.
|
package/dist/init.d.ts
CHANGED
|
@@ -39,3 +39,9 @@ export interface InitOptions {
|
|
|
39
39
|
yes?: boolean;
|
|
40
40
|
}
|
|
41
41
|
export declare function init(rawName: string | undefined, options?: InitOptions): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Put `arpAuth()` first in the eve channel's auth walk so ARP Cloud deliveries
|
|
44
|
+
* are accepted. Returns the new source, the same source when already wired,
|
|
45
|
+
* or null when the file has no recognisable auth list.
|
|
46
|
+
*/
|
|
47
|
+
export declare function wireArpAuth(src: string): string | null;
|
package/dist/init.js
CHANGED
|
@@ -13,7 +13,9 @@ import { MODEL_REACH_ENV, resolveModelScaffold } from "./model-reach.js";
|
|
|
13
13
|
* host bindings — is opt-in, because assuming them means the FDE deletes files
|
|
14
14
|
* AND undoes real setup work (an Arcana workspace + scoped key per subagent).
|
|
15
15
|
*/
|
|
16
|
-
|
|
16
|
+
// `identity` gives the agent its .agent name surface: the owner connects it
|
|
17
|
+
// from the ARP console with one click and never touches this repo again.
|
|
18
|
+
const CORE_ITEMS = ["enterprise", "arcana", "evals", "identity"];
|
|
17
19
|
// Official eve-registry limbs installed with the engineer subagent.
|
|
18
20
|
// connection/vercel is Vercel-Connect-backed, so it is VERCEL-HOST ONLY: on a
|
|
19
21
|
// self-hosted agent it cannot get an OIDC token and the agent fails to boot.
|
|
@@ -194,6 +196,20 @@ export async function init(rawName, options = {}) {
|
|
|
194
196
|
}
|
|
195
197
|
console.log(bold("\n3/6 Writing identity, model config, memory mount, and evals …"));
|
|
196
198
|
mkdirSync(join(dir, "agent/instructions"), { recursive: true });
|
|
199
|
+
// .agent identity: the channel + peers tool came from the registry item;
|
|
200
|
+
// deliveries need arpAuth() on the eve channel, and the model needs to know
|
|
201
|
+
// what the ask_<name>_agent tools are. Both are idempotent.
|
|
202
|
+
writeFileSync(join(dir, "agent/instructions/arp.md"), arpInstructionsMd());
|
|
203
|
+
{
|
|
204
|
+
const eveChannelPath = join(dir, "agent/channels/eve.ts");
|
|
205
|
+
if (existsSync(eveChannelPath)) {
|
|
206
|
+
const wired = wireArpAuth(readFileSync(eveChannelPath, "utf8"));
|
|
207
|
+
if (wired)
|
|
208
|
+
writeFileSync(eveChannelPath, wired);
|
|
209
|
+
else
|
|
210
|
+
console.log(yellow(" ! agent/channels/eve.ts: could not add arpAuth() — add it to the channel's auth list by hand"));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
197
213
|
writeFileSync(join(dir, "agent/instructions/identity.md"), identityMd(displayName, depts));
|
|
198
214
|
try {
|
|
199
215
|
unlinkSync(join(dir, "agent/instructions.md"));
|
|
@@ -398,3 +414,35 @@ ${steps.map((s, i) => ` ${i + 1}. ${s}`).join("\n")}
|
|
|
398
414
|
${dim(" Add more later: kyb add channel <kind> · kyb add subagent <name>")}
|
|
399
415
|
`);
|
|
400
416
|
}
|
|
417
|
+
/**
|
|
418
|
+
* Put `arpAuth()` first in the eve channel's auth walk so ARP Cloud deliveries
|
|
419
|
+
* are accepted. Returns the new source, the same source when already wired,
|
|
420
|
+
* or null when the file has no recognisable auth list.
|
|
421
|
+
*/
|
|
422
|
+
export function wireArpAuth(src) {
|
|
423
|
+
if (src.includes("arpAuth("))
|
|
424
|
+
return src;
|
|
425
|
+
const lines = src.split("\n");
|
|
426
|
+
const lastImport = lines.reduce((acc, l, i) => (l.startsWith("import ") ? i : acc), -1);
|
|
427
|
+
lines.splice(lastImport + 1, 0, 'import { arpAuth } from "@kybernesis/identity";');
|
|
428
|
+
let out = lines.join("\n");
|
|
429
|
+
const comment = "// Deliveries from paired .agent peers: a per-message token ARP Cloud signs,\n // verified offline against its JWKS; skips to the next entry otherwise.";
|
|
430
|
+
if (/extraAuth:\s*\[/.test(out))
|
|
431
|
+
return out.replace(/extraAuth:\s*\[/, `extraAuth: [\n ${comment}\n arpAuth(),`);
|
|
432
|
+
if (/\bauth:\s*\[/.test(out))
|
|
433
|
+
return out.replace(/\bauth:\s*\[/, `auth: [\n ${comment}\n arpAuth(),`);
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
function arpInstructionsMd() {
|
|
437
|
+
return `## Your .agent identity
|
|
438
|
+
|
|
439
|
+
You have a registered name on the agent network. Other agents that are paired
|
|
440
|
+
with you appear as \`ask_<name>_agent\` tools (the name is their .agent name; a
|
|
441
|
+
plain \`ask_<name>\` tool, if present, is a different, non-network peer); use
|
|
442
|
+
them when a request belongs to that agent rather than to you. When a message
|
|
443
|
+
arrives from a paired agent, the caller's identity has already been verified
|
|
444
|
+
and the message has already been checked against what its owner allowed —
|
|
445
|
+
answer it as you would a trusted colleague, and honour any obligations
|
|
446
|
+
attached (for example, do not include fields you were told to redact).
|
|
447
|
+
`;
|
|
448
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kybernesis/create",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "The Kybernesis agent scaffolder and FDE toolkit: one command to a governed, remembering, multiplayer, self-testing eve agent
|
|
3
|
+
"version": "0.16.0",
|
|
4
|
+
"description": "The Kybernesis agent scaffolder and FDE toolkit: one command to a governed, remembering, multiplayer, self-testing eve agent \u2014 plus doctor and upgrade.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://kybernesis.ai",
|
|
@@ -86,6 +86,31 @@ What this arrangement costs you, and it is worth saying to the client:
|
|
|
86
86
|
presents as the agent "breaking".
|
|
87
87
|
- **Ask the vendor's terms question before a client demo**, not after.
|
|
88
88
|
|
|
89
|
+
### A Claude subscription expires on a ~28-day clock, and lies on the way out
|
|
90
|
+
|
|
91
|
+
Claude is the third provider and behaves differently enough to plan around.
|
|
92
|
+
Grok and ChatGPT are a file a CLI keeps fresh; Claude is a **proxy process**
|
|
93
|
+
holding Claude Code's own OAuth (`scripts/claude-subscription.sh` in
|
|
94
|
+
`@kybernesis/exe`). Two things follow, both learned on Sid:
|
|
95
|
+
|
|
96
|
+
- **The sign-in has a hard expiry of about 28 days.** The access token refreshes
|
|
97
|
+
hourly and does so happily the whole time, which tells you nothing — the
|
|
98
|
+
*refresh* token underneath carries its own fixed expiry, and using it does not
|
|
99
|
+
extend it. On expiry the proxy blanks the credential file to empty strings and
|
|
100
|
+
every turn 401s. Only `login` recovers it; `reload` and restarts cannot.
|
|
101
|
+
**Diary the re-login for every subscription-backed agent you deploy.**
|
|
102
|
+
- **`/ready` cannot see a dead credential.** It reports that a credential was
|
|
103
|
+
*loaded*, not that it is *valid*, so it answers 200 over a blanked file while
|
|
104
|
+
the API 401s — `status` read "signed in, answering" straight through an
|
|
105
|
+
outage. `status` now probes `/v1/models` as well and warns from the refresh
|
|
106
|
+
expiry (`✓ sign-in valid for 27d`, escalating at 7 and 3 days). Run it on a
|
|
107
|
+
schedule; the failure is silent and looks like a model outage, so people go
|
|
108
|
+
and read Anthropic's status page instead of opening a browser.
|
|
109
|
+
|
|
110
|
+
Say the re-login cadence out loud to a client before it strands their agent at
|
|
111
|
+
a weekend. It is the one piece of operational debt this arrangement creates in
|
|
112
|
+
exchange for not billing metered API usage.
|
|
113
|
+
|
|
89
114
|
## The failure modes, each of which cost a real session
|
|
90
115
|
|
|
91
116
|
- **`EXE_MODEL` is deliberately empty after `kyb init`.** Set it from the
|