@kybernesis/create 0.26.2 → 0.26.4
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/buzz.js +11 -1
- package/dist/doctor.js +6 -1
- package/dist/systemd.d.ts +8 -0
- package/dist/systemd.js +22 -0
- package/dist/templates.js +8 -2
- package/package.json +1 -1
package/dist/buzz.js
CHANGED
|
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync
|
|
|
2
2
|
import { tmpdir, userInfo } from "node:os";
|
|
3
3
|
import { basename, join, resolve } from "node:path";
|
|
4
4
|
import { upsertEnv } from "./envfile.js";
|
|
5
|
+
import { buzzBridgeUnitsFor } from "./systemd.js";
|
|
5
6
|
import { bold, capture, dim, green, linePackage, red, run, yellow } from "./util.js";
|
|
6
7
|
/**
|
|
7
8
|
* `kyb add buzz` — get an agent ready for its owner's Buzz community.
|
|
@@ -32,7 +33,7 @@ export function buzzKeyPath(appDir) {
|
|
|
32
33
|
return join(appDir, ".buzz", "agent-key.json");
|
|
33
34
|
}
|
|
34
35
|
export function buzzBridgeUnitName(agent) {
|
|
35
|
-
return `${agent}-buzz-bridge`;
|
|
36
|
+
return `${agent.toLowerCase()}-buzz-bridge`;
|
|
36
37
|
}
|
|
37
38
|
/** The bridge's systemd unit. Pure, so the test pins what every host gets. */
|
|
38
39
|
export function buzzBridgeUnit(input) {
|
|
@@ -119,6 +120,15 @@ export function addBuzz(cwd = resolve(process.cwd())) {
|
|
|
119
120
|
console.log(yellow(" ! no docker here, so the Buzz CLI was not built; the agent can talk in Buzz but not act in it."));
|
|
120
121
|
}
|
|
121
122
|
}
|
|
123
|
+
// A bridge already serving this folder is this agent's bridge, whatever it is called.
|
|
124
|
+
// Installing another beside it would answer every message twice.
|
|
125
|
+
const existingUnits = buzzBridgeUnitsFor(cwd);
|
|
126
|
+
if (existingUnits.length > 0) {
|
|
127
|
+
console.log(dim(` bridge: ${existingUnits.join(", ")} already serves this agent`));
|
|
128
|
+
console.log(bold("\n Next:"));
|
|
129
|
+
console.log(` · The owner connects it from the Channels page: their community's address, then an admin adds ${npub} as a member.`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
122
132
|
const unitName = buzzBridgeUnitName(agent);
|
|
123
133
|
const dir = mkdtempSync(join(tmpdir(), "kyb-buzz-"));
|
|
124
134
|
try {
|
package/dist/doctor.js
CHANGED
|
@@ -3,7 +3,7 @@ import { TEMPLATE_CONTAINER_PROBE, parseTemplateContainers, templateContainerDoc
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
5
|
import { EVE_VERSION, REGISTRY_URL, bold, capture, dim, green, parseEnv, red, yellow } from "./util.js";
|
|
6
|
-
import { diagnoseManageRestart, findMatchingAgentServiceUnit } from "./systemd.js";
|
|
6
|
+
import { buzzBridgeUnitsFor, diagnoseManageRestart, findMatchingAgentServiceUnit } from "./systemd.js";
|
|
7
7
|
import { inspectEveAgent } from "./agent-limits.js";
|
|
8
8
|
import { classifyModelReach } from "./model-reach.js";
|
|
9
9
|
import { countAbandonedRuns } from "./run-store.js";
|
|
@@ -195,6 +195,11 @@ export async function doctor() {
|
|
|
195
195
|
* two changes signed off as deployed were live nowhere. Nothing looked
|
|
196
196
|
* broken — the old code simply kept doing what it did.
|
|
197
197
|
*/
|
|
198
|
+
// One bridge per agent: two answer every Buzz message twice.
|
|
199
|
+
const bridges = buzzBridgeUnitsFor(cwd);
|
|
200
|
+
if (bridges.length > 1) {
|
|
201
|
+
add("fail", `${bridges.length} Buzz bridges run for this agent (${bridges.join(", ")})`, `Each answers every message, so people get every answer twice. Keep the one deploy.sh restarts and remove the rest: sudo systemctl disable --now <unit> && sudo rm /etc/systemd/system/<unit>.service && sudo systemctl daemon-reload`);
|
|
202
|
+
}
|
|
198
203
|
const packageChange = newestPackageChange(cwd);
|
|
199
204
|
const started = new Map();
|
|
200
205
|
for (const unit of listAgentUnits()) {
|
package/dist/systemd.d.ts
CHANGED
|
@@ -21,6 +21,14 @@ export interface InstalledAgentService {
|
|
|
21
21
|
values: UnitValues;
|
|
22
22
|
mode: number;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* The Buzz bridge units that run in this agent's folder, whatever they are called.
|
|
26
|
+
*
|
|
27
|
+
* A bridge belongs to an agent by the folder it runs in, not by its name: a
|
|
28
|
+
* second unit with another name ("Kyber-buzz-bridge" beside "kyber-buzz-bridge")
|
|
29
|
+
* is a second bridge on the same key, and every message is answered twice.
|
|
30
|
+
*/
|
|
31
|
+
export declare function buzzBridgeUnitsFor(cwd: string, systemdDir?: string): string[];
|
|
24
32
|
export declare function findMatchingAgentServiceUnit(cwd: string, systemdDir?: string): InstalledAgentService | null;
|
|
25
33
|
/**
|
|
26
34
|
* Refresh an existing package-generated unit. Deliberately never creates a
|
package/dist/systemd.js
CHANGED
|
@@ -83,6 +83,28 @@ function dropIns(dir) {
|
|
|
83
83
|
return [];
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* The Buzz bridge units that run in this agent's folder, whatever they are called.
|
|
88
|
+
*
|
|
89
|
+
* A bridge belongs to an agent by the folder it runs in, not by its name: a
|
|
90
|
+
* second unit with another name ("Kyber-buzz-bridge" beside "kyber-buzz-bridge")
|
|
91
|
+
* is a second bridge on the same key, and every message is answered twice.
|
|
92
|
+
*/
|
|
93
|
+
export function buzzBridgeUnitsFor(cwd, systemdDir = "/etc/systemd/system") {
|
|
94
|
+
try {
|
|
95
|
+
return readdirSync(systemdDir)
|
|
96
|
+
.filter((entry) => /buzz-bridge.*\.service$/.test(entry))
|
|
97
|
+
.filter((file) => {
|
|
98
|
+
const dir = readFileSync(join(systemdDir, file), "utf8").match(/^WorkingDirectory=(.+)$/m)?.[1]?.trim();
|
|
99
|
+
return dir !== undefined && resolve(dir) === resolve(cwd);
|
|
100
|
+
})
|
|
101
|
+
.map((file) => file.replace(/\.service$/, ""))
|
|
102
|
+
.sort();
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
86
108
|
export function findMatchingAgentServiceUnit(cwd, systemdDir = "/etc/systemd/system") {
|
|
87
109
|
try {
|
|
88
110
|
for (const file of readdirSync(systemdDir).filter((entry) => entry.endsWith("-agent.service"))) {
|
package/dist/templates.js
CHANGED
|
@@ -306,7 +306,8 @@ export default multiplayerSlackChannel({
|
|
|
306
306
|
return onExe
|
|
307
307
|
? {
|
|
308
308
|
file: "linq.ts",
|
|
309
|
-
content: `import {
|
|
309
|
+
content: `import { progressEvents } from "@kybernesis/cards";
|
|
310
|
+
import { channelIdentity } from "@kybernesis/enterprise";
|
|
310
311
|
import { linqEnvCredentials, linqSenderIdentity } from "@kybernesis/exe/linq";
|
|
311
312
|
import { linqChannel } from "eve/channels/linq";
|
|
312
313
|
|
|
@@ -317,6 +318,10 @@ import { linqChannel } from "eve/channels/linq";
|
|
|
317
318
|
//
|
|
318
319
|
// A sender is a control-plane person, never a phone number: an unlinked number
|
|
319
320
|
// gets one text with a claim link and nothing else.
|
|
321
|
+
//
|
|
322
|
+
// A text thread shows nothing between a request and its answer, so when the
|
|
323
|
+
// agent starts a long job it sends one "on it" line first (\`working_on_it\`,
|
|
324
|
+
// from @kybernesis/notify) and \`progressEvents\` posts it here as it happens.
|
|
320
325
|
const issuer = process.env.KYBERNESIS_ISSUER ?? "https://agent.kybernesis.ai";
|
|
321
326
|
const credential = process.env.KYBERNESIS_AGENT_CREDENTIAL;
|
|
322
327
|
const agentName = process.env.KYBERNESIS_AGENT;
|
|
@@ -324,6 +329,7 @@ const agentName = process.env.KYBERNESIS_AGENT;
|
|
|
324
329
|
export default linqChannel({
|
|
325
330
|
credentials: linqEnvCredentials(),
|
|
326
331
|
...(agentName ? { userName: agentName } : {}),
|
|
332
|
+
events: progressEvents(),
|
|
327
333
|
onMessage: linqSenderIdentity({
|
|
328
334
|
issuer,
|
|
329
335
|
agentName,
|
|
@@ -331,7 +337,7 @@ export default linqChannel({
|
|
|
331
337
|
}),
|
|
332
338
|
});
|
|
333
339
|
`,
|
|
334
|
-
deps: ["@kybernesis/exe", "@kybernesis/enterprise"],
|
|
340
|
+
deps: ["@kybernesis/exe", "@kybernesis/enterprise", "@kybernesis/cards"],
|
|
335
341
|
registryItems: [],
|
|
336
342
|
env: [],
|
|
337
343
|
steps: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kybernesis/create",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.4",
|
|
4
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",
|