Further updates to configure

This commit is contained in:
Raven Scott
2026-04-22 03:07:28 -04:00
parent 5eb559c554
commit cb6f643273
15 changed files with 348 additions and 9 deletions
+11 -1
View File
@@ -502,7 +502,7 @@ function bareAgentPathAllowed(absPath) {
* ctx: Record<string, unknown>,
* toolName: string,
* argsJson: string,
* paths: { dir: string, config: string, cmdOut: string, workspaceSkills?: string, skillsGlobal?: string },
* paths: { dir: string, config: string, cmdOut: string, workspace?: string, workspaceSkills?: string, skillsGlobal?: string },
* signal?: AbortSignal,
* appendProgress: (line: string) => void,
* home: string,
@@ -880,6 +880,16 @@ async function bareAgentDispatchTool(o) {
const merged = bareAgentMergeConfigPatch(configRef.current, patch)
configRef.current = merged
await bareAgentSaveConfigFromTools(ctx, paths, merged)
if (
Object.prototype.hasOwnProperty.call(patch, 'owner_name') ||
Object.prototype.hasOwnProperty.call(patch, 'agent_label')
) {
const workspace =
typeof paths.workspace === 'string'
? paths.workspace
: paths.dir + '/workspace'
await bareAgentSyncWorkspaceFromConfig(ctx, { workspace }, merged)
}
appendProgress('edit_agent_config')
return bareAgentJsonResult({ ok: true, saved: true })
}
@@ -359,6 +359,7 @@ async function bareAgentRunSetupOnly(ctx, argv0) {
try {
await bareAgentEnsureWorkspace(ctx, paths)
await bareAgentEnsureSkillTemplates(ctx, paths)
await bareAgentSyncWorkspaceFromConfig(ctx, paths, config)
} catch {
bareAgentErr(
ctx,
@@ -459,6 +460,7 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
await bareAgentEnsureWorkspace(ctx, paths)
await bareAgentEnsureSkillTemplates(ctx, paths)
if (needWizard) await bareAgentSyncWorkspaceFromConfig(ctx, paths, config)
const workspacePromptBlock = await bareAgentLoadWorkspacePrompt(
ctx,
paths,
@@ -157,6 +157,96 @@ async function bareAgentEnsureSkillTemplates(ctx, paths) {
}
}
/**
* @param {Record<string, unknown>} ctx
* @param {string} text
*/
function bareAgentWorkspaceEncode(ctx, text) {
const s = String(text)
if (
typeof ctx.b4a !== 'undefined' &&
ctx.b4a &&
typeof ctx.b4a.from === 'function'
)
return ctx.b4a.from(s)
return new TextEncoder().encode(s)
}
/**
* @param {Record<string, unknown>} config
*/
function bareAgentIdentityMarkdownForConfig(config) {
const label = String(config.agent_label || '').trim() || 'BareAgent'
const owner = String(config.owner_name || '').trim()
const role = owner
? 'Decentralized OS intelligence for **' +
owner +
'** · upstream [bare-operating-system](https://git.ssh.surf/snxraven/bare-operating-system).'
: 'Decentralized OS Intelligence for snxraven\'s bare-operating-system'
return (
'# IDENTITY.md\n\n' +
'**Name:** ' +
label +
'\n' +
'**Role:** ' +
role +
'\n' +
'**Emoji:** 🦾\n' +
'**Version:** 0.1\n'
)
}
/**
* @param {Record<string, unknown>} config
*/
function bareAgentUserMarkdownForConfig(config) {
const owner = String(config.owner_name || '').trim()
const opLine = owner
? '- **Operator (this Hyperdrive):** ' + owner + '\n'
: '- **Operator:** (set `owner_name` via `agent --config` or `edit_agent_config`)\n'
return (
'# USER.md - About the Owner\n\n' +
opLine +
'- **Upstream maintainer (repo):** snxraven\n' +
'- **Location:** Atlanta, Georgia, US\n' +
'- **Expertise:** P2P systems, Bare runtime, Hyperdrive, decentralized identity, POSIX-in-JS\n' +
'- **Preferences:** Concise technical answers, bullet points, no corporate speak, direct honesty\n' +
'- **Permissions:** Full access to system drive and personal Hyperdrive within tool policy\n'
)
}
/**
* Rewrite IDENTITY.md / USER.md from ~/.agent/config.json (owner_name, agent_label).
* Call after seeding workspace or when those keys change.
* @param {Record<string, unknown>} ctx
* @param {{ workspace: string }} paths
* @param {Record<string, unknown>} config
*/
async function bareAgentSyncWorkspaceFromConfig(ctx, paths, config) {
const vfs = ctx.vfs
if (!vfs || typeof vfs.writeFile !== 'function' || typeof vfs.mkdir !== 'function')
return
const label = String(config.agent_label || '').trim()
const owner = String(config.owner_name || '').trim()
if (!label && !owner) return
try {
await vfs.mkdir(paths.workspace, { recursive: true })
} catch {
return
}
try {
const idMd = bareAgentIdentityMarkdownForConfig(config)
await vfs.writeFile(
paths.workspace + '/IDENTITY.md',
bareAgentWorkspaceEncode(ctx, idMd)
)
const userMd = bareAgentUserMarkdownForConfig(config)
await vfs.writeFile(paths.workspace + '/USER.md', bareAgentWorkspaceEncode(ctx, userMd))
} catch {
/* ignore — best-effort */
}
}
/**
* Build concatenated system prompt block (Markdown) from workspace files.
* @param {Record<string, unknown>} ctx
@@ -24,6 +24,8 @@ This tree follows the **agent** Markdown workspace convention: “soul” files
Seeded examples in this repo (under **`skills/`**): **`p2p-os-status`** (P2P / drive health style checks) and **`bare-os-kernel-proc`** (authoritative **`/proc/bare_os/*`** reads vs man-page guessing).
After **`agent --config`** / **`--setup`** (or changing **`owner_name`** / **`agent_label`** via **`edit_agent_config`**), **`IDENTITY.md`** and **`USER.md`** are regenerated from **`config.json`** so the workspace matches the operator and agent label.
## Editing
1. Change files under **`~/.agent/workspace/`** on your **personal** drive.
@@ -14,6 +14,7 @@ const CODE = readFileSync(
function load(extra = {}) {
const sandbox = {
TextDecoder,
TextEncoder,
Uint8Array,
console,
...extra
@@ -145,3 +146,29 @@ test('bareAgentEnsureSkillTemplates copies skill seeds when missing', async (t)
t.ok(written.some(([p]) => p === '/home/x/.agent/workspace/skills/bare-os-kernel-proc/SKILL.md'))
t.ok(written.some(([p]) => p === '/home/x/.agent/skill-loader.js'))
})
test('bareAgentSyncWorkspaceFromConfig writes IDENTITY and USER from config', async (t) => {
const written = []
const vfs = {
async mkdir(_p, _o) {},
async writeFile(p, buf) {
const txt =
buf instanceof Uint8Array ? new TextDecoder().decode(buf) : String(buf)
written.push([p, txt])
}
}
const s = load()
const sync = /** @type {(ctx: object, paths: object, cfg: object) => Promise<void>} */ (
s.bareAgentSyncWorkspaceFromConfig
)
await sync(
{ vfs, b4a: null },
{ workspace: '/home/x/.agent/workspace' },
{ owner_name: 'Raven', agent_label: 'Bear' }
)
const id = written.find(([p]) => p === '/home/x/.agent/workspace/IDENTITY.md')
t.ok(id && id[1].includes('**Name:** Bear'))
t.ok(id && id[1].includes('Raven'))
const user = written.find(([p]) => p === '/home/x/.agent/workspace/USER.md')
t.ok(user && user[1].includes('Raven'))
})