Further updates to configure
This commit is contained in:
@@ -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'))
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user