@aerovato/operator-helper 1.9.0 → 1.11.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/README.md +1 -1
- package/dist/index.js +265 -96
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ Restart the harness, then run `/operator:user-init` in a new conversation to beg
|
|
|
43
43
|
|
|
44
44
|
### Usage
|
|
45
45
|
|
|
46
|
-
Users interact with Operator through the harness commands `/operator:user-init`, `/operator:project-init`,
|
|
46
|
+
Users interact with Operator through the harness commands `/operator:user-init`, `/operator:project-init`, and `/operator:index`. These commands guide the working agent, which uses Operator Helper for setup, status, and validation.
|
|
47
47
|
|
|
48
48
|
Run each Operator command in a new conversation so the agent can focus on that operation with a clean working context. Initialization preserves existing content. Project setup configures `.operator/` in the global Git ignore but does not automatically untrack files already committed.
|
|
49
49
|
|
package/dist/index.js
CHANGED
|
@@ -33,6 +33,19 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
33
33
|
return to;
|
|
34
34
|
};
|
|
35
35
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
36
|
+
var __returnValue = (v) => v;
|
|
37
|
+
function __exportSetter(name, newValue) {
|
|
38
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
39
|
+
}
|
|
40
|
+
var __export = (target, all) => {
|
|
41
|
+
for (var name in all)
|
|
42
|
+
__defProp(target, name, {
|
|
43
|
+
get: all[name],
|
|
44
|
+
enumerable: true,
|
|
45
|
+
configurable: true,
|
|
46
|
+
set: __exportSetter.bind(all, name)
|
|
47
|
+
});
|
|
48
|
+
};
|
|
36
49
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
37
50
|
|
|
38
51
|
// ../../node_modules/.bun/cli-table3@0.6.5/node_modules/cli-table3/src/debug.js
|
|
@@ -8659,6 +8672,20 @@ var require_public_api = __commonJS(function(exports) {
|
|
|
8659
8672
|
exports.stringify = stringify;
|
|
8660
8673
|
});
|
|
8661
8674
|
|
|
8675
|
+
// ../core/src/prompts/preamble-v1.ts
|
|
8676
|
+
var exports_preamble_v1 = {};
|
|
8677
|
+
__export(exports_preamble_v1, {
|
|
8678
|
+
PREAMBLE_PROMPT: () => PREAMBLE_PROMPT,
|
|
8679
|
+
PREAMBLE_TENETS: () => PREAMBLE_TENETS
|
|
8680
|
+
});
|
|
8681
|
+
|
|
8682
|
+
// ../core/src/prompts/preamble-v2.ts
|
|
8683
|
+
var exports_preamble_v2 = {};
|
|
8684
|
+
__export(exports_preamble_v2, {
|
|
8685
|
+
PREAMBLE_PROMPT: () => PREAMBLE_PROMPT2,
|
|
8686
|
+
PREAMBLE_TENETS: () => PREAMBLE_TENETS2
|
|
8687
|
+
});
|
|
8688
|
+
|
|
8662
8689
|
// src/index.ts
|
|
8663
8690
|
import { homedir } from "node:os";
|
|
8664
8691
|
// ../../node_modules/.bun/effect@4.0.0-beta.107/node_modules/effect/dist/Pipeable.js
|
|
@@ -15319,7 +15346,7 @@ var log = (...args) => consoleWith((console2) => sync(() => {
|
|
|
15319
15346
|
// package.json
|
|
15320
15347
|
var package_default = {
|
|
15321
15348
|
name: "@aerovato/operator-helper",
|
|
15322
|
-
version: "1.
|
|
15349
|
+
version: "1.11.0",
|
|
15323
15350
|
description: "Installation and setup CLI for Operator Memory",
|
|
15324
15351
|
license: "BSD-3-Clause",
|
|
15325
15352
|
author: "Aerovato Research",
|
|
@@ -15509,16 +15536,6 @@ function runProcess(executable, arguments_, cwd, environment) {
|
|
|
15509
15536
|
};
|
|
15510
15537
|
});
|
|
15511
15538
|
}
|
|
15512
|
-
async function pathKind(path) {
|
|
15513
|
-
try {
|
|
15514
|
-
const info = await lstat(path);
|
|
15515
|
-
return info.isFile() ? "file" : info.isDirectory() ? "directory" : "other";
|
|
15516
|
-
} catch (error) {
|
|
15517
|
-
if (isNodeError(error) && error.code === "ENOENT")
|
|
15518
|
-
return "missing";
|
|
15519
|
-
throw error;
|
|
15520
|
-
}
|
|
15521
|
-
}
|
|
15522
15539
|
async function readOptionalFile(path) {
|
|
15523
15540
|
try {
|
|
15524
15541
|
return await readFile3(path, "utf8");
|
|
@@ -16479,37 +16496,21 @@ function commandFailure(result, fallback) {
|
|
|
16479
16496
|
// src/commands/install/codex.ts
|
|
16480
16497
|
import { mkdir as mkdir2, writeFile as writeFile3 } from "node:fs/promises";
|
|
16481
16498
|
import { join as join2 } from "node:path";
|
|
16482
|
-
var
|
|
16483
|
-
`;
|
|
16499
|
+
var MARKETPLACE_SOURCE = "https://github.com/aerovato/operator-memory.git";
|
|
16484
16500
|
var MARKETPLACE_NAME = "operator-memory";
|
|
16485
|
-
var
|
|
16486
|
-
var PLUGIN_ID2 = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`;
|
|
16487
|
-
var MARKETPLACE = `${JSON.stringify({
|
|
16488
|
-
name: MARKETPLACE_NAME,
|
|
16489
|
-
plugins: [
|
|
16490
|
-
{
|
|
16491
|
-
name: PLUGIN_NAME,
|
|
16492
|
-
source: {
|
|
16493
|
-
source: "npm",
|
|
16494
|
-
package: "@aerovato/operator-codex",
|
|
16495
|
-
version: "latest"
|
|
16496
|
-
},
|
|
16497
|
-
policy: { installation: "AVAILABLE" }
|
|
16498
|
-
}
|
|
16499
|
-
]
|
|
16500
|
-
}, null, 2)}
|
|
16501
|
-
`;
|
|
16501
|
+
var PLUGIN_ID2 = `aerovato@${MARKETPLACE_NAME}`;
|
|
16502
16502
|
var installCodex = fn2("installCodex")(function* (context) {
|
|
16503
|
-
const
|
|
16504
|
-
if (!marketplace.ok)
|
|
16505
|
-
return marketplace.result;
|
|
16506
|
-
const addMarketplace = yield* runProcess("codex", ["plugin", "marketplace", "add", marketplace.path, "--json"], context.cwd, { NPM_CONFIG_MIN_RELEASE_AGE: "0" });
|
|
16503
|
+
const addMarketplace = yield* runProcess("codex", ["plugin", "marketplace", "add", MARKETPLACE_SOURCE, "--ref", "main", "--json"], context.cwd, { NPM_CONFIG_MIN_RELEASE_AGE: "0" });
|
|
16507
16504
|
if (!addMarketplace.ok && isMissingBinary(addMarketplace.error)) {
|
|
16508
|
-
return yield* registerDesktopMarketplace(context
|
|
16505
|
+
return yield* registerDesktopMarketplace(context);
|
|
16509
16506
|
}
|
|
16510
16507
|
const addFailure = commandFailure2(addMarketplace, "Codex marketplace installation failed");
|
|
16511
16508
|
if (addFailure !== null)
|
|
16512
16509
|
return addFailure;
|
|
16510
|
+
const upgrade = yield* runProcess("codex", ["plugin", "marketplace", "upgrade", MARKETPLACE_NAME, "--json"], context.cwd, { NPM_CONFIG_MIN_RELEASE_AGE: "0" });
|
|
16511
|
+
const upgradeFailure = commandFailure2(upgrade, "Codex marketplace upgrade failed");
|
|
16512
|
+
if (upgradeFailure !== null)
|
|
16513
|
+
return upgradeFailure;
|
|
16513
16514
|
const install = yield* runProcess("codex", ["plugin", "add", PLUGIN_ID2, "--json"], context.cwd, {
|
|
16514
16515
|
NPM_CONFIG_MIN_RELEASE_AGE: "0"
|
|
16515
16516
|
});
|
|
@@ -16535,48 +16536,17 @@ var installCodex = fn2("installCodex")(function* (context) {
|
|
|
16535
16536
|
`)
|
|
16536
16537
|
};
|
|
16537
16538
|
});
|
|
16538
|
-
function writeMarketplace(home) {
|
|
16539
|
-
return promise2(async () => {
|
|
16540
|
-
const root = join2(home, ".operator-helper", "codex-marketplace");
|
|
16541
|
-
const marker = join2(root, ".operator-managed");
|
|
16542
|
-
const marketplace = join2(root, ".agents", "plugins", "marketplace.json");
|
|
16543
|
-
try {
|
|
16544
|
-
const kind = await pathKind(root);
|
|
16545
|
-
if (kind !== "missing" && (kind !== "directory" || await readOptionalFile(marker) !== MARKETPLACE_MARKER)) {
|
|
16546
|
-
return {
|
|
16547
|
-
ok: false,
|
|
16548
|
-
result: {
|
|
16549
|
-
exitCode: 1,
|
|
16550
|
-
output: `✗ Preserved unmanaged Codex marketplace at ${root}`
|
|
16551
|
-
}
|
|
16552
|
-
};
|
|
16553
|
-
}
|
|
16554
|
-
await mkdir2(join2(root, ".agents", "plugins"), { recursive: true });
|
|
16555
|
-
await writeFile3(marker, MARKETPLACE_MARKER);
|
|
16556
|
-
await writeFile3(marketplace, MARKETPLACE);
|
|
16557
|
-
return { ok: true, path: root };
|
|
16558
|
-
} catch (error) {
|
|
16559
|
-
return {
|
|
16560
|
-
ok: false,
|
|
16561
|
-
result: {
|
|
16562
|
-
exitCode: 1,
|
|
16563
|
-
output: `✗ Could not prepare Codex marketplace: ${getErrorMessage(error)}`
|
|
16564
|
-
}
|
|
16565
|
-
};
|
|
16566
|
-
}
|
|
16567
|
-
});
|
|
16568
|
-
}
|
|
16569
16539
|
function isMissingBinary(error) {
|
|
16570
16540
|
return error.startsWith("NotFound:");
|
|
16571
16541
|
}
|
|
16572
|
-
function registerDesktopMarketplace(context
|
|
16542
|
+
function registerDesktopMarketplace(context) {
|
|
16573
16543
|
return promise2(async () => {
|
|
16574
16544
|
const codexHome = process.env.CODEX_HOME || join2(context.home, ".codex");
|
|
16575
16545
|
const config = join2(codexHome, "config.toml");
|
|
16576
16546
|
try {
|
|
16577
16547
|
const content = await readOptionalFile(config);
|
|
16578
16548
|
await mkdir2(codexHome, { recursive: true });
|
|
16579
|
-
await writeFile3(config, upsertMarketplaceTable(content
|
|
16549
|
+
await writeFile3(config, upsertMarketplaceTable(content));
|
|
16580
16550
|
} catch (error) {
|
|
16581
16551
|
return {
|
|
16582
16552
|
exitCode: 1,
|
|
@@ -16593,11 +16563,12 @@ function registerDesktopMarketplace(context, marketplacePath) {
|
|
|
16593
16563
|
};
|
|
16594
16564
|
});
|
|
16595
16565
|
}
|
|
16596
|
-
function upsertMarketplaceTable(content
|
|
16566
|
+
function upsertMarketplaceTable(content) {
|
|
16597
16567
|
const header = `[marketplaces.${MARKETPLACE_NAME}]`;
|
|
16598
16568
|
const block = `${header}
|
|
16599
|
-
source_type = "
|
|
16600
|
-
source = ${JSON.stringify(
|
|
16569
|
+
source_type = "git"
|
|
16570
|
+
source = ${JSON.stringify(MARKETPLACE_SOURCE)}
|
|
16571
|
+
ref = "main"
|
|
16601
16572
|
`;
|
|
16602
16573
|
if (content === null)
|
|
16603
16574
|
return block;
|
|
@@ -16678,7 +16649,7 @@ function profileResult(profile, result) {
|
|
|
16678
16649
|
}
|
|
16679
16650
|
|
|
16680
16651
|
// src/commands/install/kiro.ts
|
|
16681
|
-
import { mkdir as mkdir3, writeFile as writeFile4 } from "node:fs/promises";
|
|
16652
|
+
import { mkdir as mkdir3, rm as rm2, writeFile as writeFile4 } from "node:fs/promises";
|
|
16682
16653
|
import { dirname as dirname2, join as join3 } from "node:path";
|
|
16683
16654
|
|
|
16684
16655
|
// src/templates/kiro.ts
|
|
@@ -16749,26 +16720,12 @@ description: Build or refresh the Operator Project Index. Use only when the user
|
|
|
16749
16720
|
If the Project Brain is missing, tell the user to invoke \`/operator-project-init\` to set it up.
|
|
16750
16721
|
|
|
16751
16722
|
${RECOVERY("index init")}`;
|
|
16752
|
-
var REPAIR = `---
|
|
16753
|
-
name: operator-repair
|
|
16754
|
-
description: Diagnose and repair Operator memory load failures. Use only when the user invokes /operator-repair.
|
|
16755
|
-
---
|
|
16756
|
-
|
|
16757
|
-
# Operator Memory Repair
|
|
16758
|
-
|
|
16759
|
-
1. Run \`operator-helper version\`. If an update is available, run \`operator-helper upgrade\` before continuing.
|
|
16760
|
-
2. Run \`operator-helper memory check\`. If no issues are detected, stop. Otherwise, repair only the reported load failures without initializing absent partitions. Rerun \`operator-helper memory check\` to confirm the repair, then read the applicable Operator memory documents.
|
|
16761
|
-
|
|
16762
|
-
If \`~/.kiro/hooks/operator-memory.json\` or \`~/.kiro/steering/operator-memory.md\` is missing, tell the user to run \`operator-helper install kiro\` and start a new session.
|
|
16763
|
-
|
|
16764
|
-
${RECOVERY("memory check")}`;
|
|
16765
16723
|
var KIRO_FILES = [
|
|
16766
16724
|
{ path: "hooks/operator-memory.json", content: HOOK },
|
|
16767
16725
|
{ path: "steering/operator-memory.md", content: STEERING },
|
|
16768
16726
|
{ path: "skills/operator-user-init/SKILL.md", content: USER_INIT },
|
|
16769
16727
|
{ path: "skills/operator-project-init/SKILL.md", content: PROJECT_INIT },
|
|
16770
|
-
{ path: "skills/operator-index/SKILL.md", content: INDEX }
|
|
16771
|
-
{ path: "skills/operator-repair/SKILL.md", content: REPAIR }
|
|
16728
|
+
{ path: "skills/operator-index/SKILL.md", content: INDEX }
|
|
16772
16729
|
];
|
|
16773
16730
|
|
|
16774
16731
|
// src/commands/install/kiro.ts
|
|
@@ -16788,6 +16745,7 @@ var installKiro = fn2("installKiro")(function* (context) {
|
|
|
16788
16745
|
function writeKiroFiles(kiroHome) {
|
|
16789
16746
|
return promise2(async () => {
|
|
16790
16747
|
try {
|
|
16748
|
+
await rm2(join3(kiroHome, "skills", "operator-repair", "SKILL.md"), { force: true });
|
|
16791
16749
|
for (const file of KIRO_FILES) {
|
|
16792
16750
|
const path = join3(kiroHome, file.path);
|
|
16793
16751
|
await mkdir3(dirname2(path), { recursive: true });
|
|
@@ -17136,7 +17094,7 @@ var memoryCheck = fn2("memoryCheck")(function* (context) {
|
|
|
17136
17094
|
}
|
|
17137
17095
|
if (!failed) {
|
|
17138
17096
|
lines.push(`
|
|
17139
|
-
No
|
|
17097
|
+
No memory load failures detected.`);
|
|
17140
17098
|
}
|
|
17141
17099
|
return { exitCode: failed ? 1 : 0, output: lines.join(`
|
|
17142
17100
|
`) };
|
|
@@ -17149,8 +17107,60 @@ function entries(snapshot) {
|
|
|
17149
17107
|
];
|
|
17150
17108
|
}
|
|
17151
17109
|
|
|
17152
|
-
// ../core/src/
|
|
17153
|
-
|
|
17110
|
+
// ../core/src/preamble-rollout.ts
|
|
17111
|
+
import { execFileSync } from "node:child_process";
|
|
17112
|
+
import { createHash } from "node:crypto";
|
|
17113
|
+
import { readFileSync } from "node:fs";
|
|
17114
|
+
import { platform } from "node:os";
|
|
17115
|
+
var ROLLOUT_NAMESPACE = "operator-preamble-rollout-v1:";
|
|
17116
|
+
function selectPreambleVersion() {
|
|
17117
|
+
if (process.env.OPERATOR_PREAMBLE_BETA === "1") {
|
|
17118
|
+
return "2.0";
|
|
17119
|
+
}
|
|
17120
|
+
const machineId = readMachineId();
|
|
17121
|
+
if (machineId === null) {
|
|
17122
|
+
return "1.1";
|
|
17123
|
+
}
|
|
17124
|
+
const bucket = createHash("sha256").update(`${ROLLOUT_NAMESPACE}${machineId}`).digest().readUInt32BE(0) % 100;
|
|
17125
|
+
return bucket < 20 ? "2.0" : "1.1";
|
|
17126
|
+
}
|
|
17127
|
+
function readMachineId() {
|
|
17128
|
+
try {
|
|
17129
|
+
switch (platform()) {
|
|
17130
|
+
case "linux": {
|
|
17131
|
+
const value = readFileSync("/etc/machine-id", "utf8").trim().toLowerCase();
|
|
17132
|
+
return /^[a-f0-9]{32}$/.test(value) && !/^0+$/.test(value) ? value : null;
|
|
17133
|
+
}
|
|
17134
|
+
case "darwin": {
|
|
17135
|
+
const output = execFileSync("/usr/sbin/ioreg", ["-rd1", "-c", "IOPlatformExpertDevice"], {
|
|
17136
|
+
encoding: "utf8",
|
|
17137
|
+
timeout: 2000,
|
|
17138
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
17139
|
+
});
|
|
17140
|
+
return normalizeUuid(output.match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/)?.[1]);
|
|
17141
|
+
}
|
|
17142
|
+
case "win32": {
|
|
17143
|
+
const output = execFileSync("reg.exe", ["query", "HKLM\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid", "/reg:64"], {
|
|
17144
|
+
encoding: "utf8",
|
|
17145
|
+
timeout: 2000,
|
|
17146
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
17147
|
+
});
|
|
17148
|
+
return normalizeUuid(output.match(/MachineGuid\s+REG_SZ\s+(\S+)/i)?.[1]);
|
|
17149
|
+
}
|
|
17150
|
+
default:
|
|
17151
|
+
return null;
|
|
17152
|
+
}
|
|
17153
|
+
} catch {
|
|
17154
|
+
return null;
|
|
17155
|
+
}
|
|
17156
|
+
}
|
|
17157
|
+
function normalizeUuid(value) {
|
|
17158
|
+
const normalized = value?.toLowerCase();
|
|
17159
|
+
return normalized !== undefined && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(normalized) && normalized !== "00000000-0000-0000-0000-000000000000" ? normalized : null;
|
|
17160
|
+
}
|
|
17161
|
+
|
|
17162
|
+
// ../core/src/prompts/preamble-v1.ts
|
|
17163
|
+
var PREAMBLE_PROMPT = `<operator-guidance version="1.1">
|
|
17154
17164
|
|
|
17155
17165
|
# Operator
|
|
17156
17166
|
|
|
@@ -17329,7 +17339,7 @@ Examples — record brain entries in scenarios like these:
|
|
|
17329
17339
|
</example>
|
|
17330
17340
|
|
|
17331
17341
|
</operator-guidance>`;
|
|
17332
|
-
var PREAMBLE_TENETS = `<operator-tenets>
|
|
17342
|
+
var PREAMBLE_TENETS = `<operator-tenets version="1.1">
|
|
17333
17343
|
## **REMEMBER: Core Tenets**
|
|
17334
17344
|
|
|
17335
17345
|
<important>
|
|
@@ -17344,12 +17354,164 @@ var PREAMBLE_TENETS = `<operator-tenets>
|
|
|
17344
17354
|
**You must remember these tenets and apply them while you work.**
|
|
17345
17355
|
</operator-tenets>`;
|
|
17346
17356
|
|
|
17357
|
+
// ../core/src/prompts/preamble-v2.ts
|
|
17358
|
+
var PREAMBLE_PROMPT2 = `<operator-guidance version="2.0">
|
|
17359
|
+
|
|
17360
|
+
# Operator
|
|
17361
|
+
|
|
17362
|
+
You are working under **Operator by Aerovato Research**. Operator Memory is a plugin that gives you a human-readable **brain** on disk so knowledge survives your ephemeral conversation. **Consult and proactively maintain it** using the guidance below. This fixed preamble introduces the system; available memory follows.
|
|
17363
|
+
|
|
17364
|
+
## The Brain
|
|
17365
|
+
|
|
17366
|
+
\`\`\`
|
|
17367
|
+
Operator Memory
|
|
17368
|
+
├── User Partition (~/.operator/user/) private; global; applies to all projects
|
|
17369
|
+
│ ├── operator.md User Instructions
|
|
17370
|
+
│ ├── catalog.md User Catalog
|
|
17371
|
+
│ └── … Freeform user memory
|
|
17372
|
+
├── Project Private (.operator/) private; local; default for new project work
|
|
17373
|
+
│ ├── index/ Project Index (codebase map)
|
|
17374
|
+
│ ├── operator.md Operator Instructions
|
|
17375
|
+
│ ├── catalog.md Project Partition Catalog (brain map)
|
|
17376
|
+
│ └── … Freeform project brain
|
|
17377
|
+
└── Project Shared (.operator-shared/) optional; published with the repo; team-wide knowledge
|
|
17378
|
+
└── (same layout as Project Private)
|
|
17379
|
+
\`\`\`
|
|
17380
|
+
|
|
17381
|
+
The User Partition is cross-project. The Project Brain consists of both Project Partitions, split into Private and Shared so local work and published knowledge stay distinct.
|
|
17382
|
+
|
|
17383
|
+
---
|
|
17384
|
+
|
|
17385
|
+
**Follow the memory-aware workflow:** user prompts → consult the Brain → do the work → update the Brain. Do not work from scratch when relevant memory exists or leave durable findings only in the conversation. Maintain the brain without user intervention.
|
|
17386
|
+
|
|
17387
|
+
## Consult the Brain
|
|
17388
|
+
|
|
17389
|
+
Before searching or opening files, use the context already injected below. Don't reread already injected files. Open additional context and freeform files when appropriate.
|
|
17390
|
+
|
|
17391
|
+
- \`operator.md\` — always-loaded context and instructions, like a more sophisticated \`AGENTS.md\` file. Follow instruction authority: **Project Private > User > Project Shared**.
|
|
17392
|
+
- \`catalog.md\` — maps one partition's Brain documents. Root catalogs are injected; linked sub-catalogs and document bodies are not. **Follow matching Read If entries through sub-catalogs to relevant documents before exploring or implementing**. Don't skip reading because code or context seems sufficient; you'll need to update documents if truth changes. Read only what's needed.
|
|
17393
|
+
- \`index/*\`, \`index/index.md\` — project indexes; maps codebase structure and intent. Main index (\`index/index.md\`) and subindex listings are injected; read relevant subindexes for info; combine indexes with your other search tools before deep code reads.
|
|
17394
|
+
- Freeform Documents — brain knowledge. Specifications, guides, research, product vision, plans, skills, style guides, workflows, long-term memory, etc. Documents can be more than Markdown; images, folders, mini-repos, artifact-backed skills, etc.
|
|
17395
|
+
|
|
17396
|
+
## Update the Brain
|
|
17397
|
+
|
|
17398
|
+
Proactively preserve context, decisions, big-picture contracts, guides, conventions, rules, reused workflows, meta-requirements, etc., information future sessions will need. Preserve essential orientation and durable knowledge; do not duplicate implementation details. Do not restate implementation details, or document trivial changes. No bloating documents with minor tweaks.
|
|
17399
|
+
|
|
17400
|
+
### Placement and Authority
|
|
17401
|
+
|
|
17402
|
+
- Place project content per \`operator.md\` shared/private placement policy, else common sense and existing brain conventions, else Private. Record permanent share patterns in appropriate \`operator.md\`; don't leak private details in shared \`operator.md\`.
|
|
17403
|
+
- Modify the user partition when the user asks to remember or record project-agnostic content. Do not place project-specific facts, constraints, or instructions there. Do not infer personal traits or perferences from incidental behavior; only if repeated or stated explicitly by user.
|
|
17404
|
+
- **Shared must never reference private files, paths, or private-only material.** Private may reference Shared.
|
|
17405
|
+
- Keep one canonical home for each fact and partitions mostly mutually exclusive. Private instructions may override Shared instructions.
|
|
17406
|
+
|
|
17407
|
+
### Operator Instructions
|
|
17408
|
+
|
|
17409
|
+
Each partition has one \`operator.md\` for essential, always-loaded context and instructions. It should do everything an \`AGENTS.md\` file does but better.
|
|
17410
|
+
|
|
17411
|
+
- Project: contains purpose, architectural overview, essential working context, and project rules, conventions, sharing policy, and more. Whatever needs to be loaded into context immediately, put here.
|
|
17412
|
+
- **Proactively maintain established context; do not wait for a request to document it.**
|
|
17413
|
+
- User: contains relevant user background and context, response preferences, workflow, autonomy, engineering principles, working style, coding preferences, style guides, global operating instructions, global rules, global memory, inferred preferences, and more.
|
|
17414
|
+
|
|
17415
|
+
Keep these files concise and structured for the user. Detailed or task-specific knowledge belongs in cataloged freeform files, not in an ever-growing \`operator.md\`.
|
|
17416
|
+
|
|
17417
|
+
### Project Index
|
|
17418
|
+
|
|
17419
|
+
- Every index file requires YAML \`description\` and \`read_if\`. The main index is \`<partition>/index/index.md\`, titled \`Private Project Index\` or \`Shared Project Index\`.
|
|
17420
|
+
- Maintain a sole existing index as the main map. If both partitions have indexes, Shared owns the publishable codebase map and Private owns private corpora; keep coverage mutually exclusive.
|
|
17421
|
+
- Update indexes after new or significantly changed code and proactively correct stale or missing entries as you learn.
|
|
17422
|
+
- For larger code bases: use main as index essential navigation and split large modules into subindexes linked from main tree. Add a private subindex and main-index link for cloned reference trees.
|
|
17423
|
+
- Cover every non-ignored path in scope; use a single directory entry for large or low-value trees. Omit build/cache/dependency directories unless relevant; include ignored paths only when useful.
|
|
17424
|
+
|
|
17425
|
+
Main index (\`<partition>/index/index.md\`):
|
|
17426
|
+
|
|
17427
|
+
\`\`\`markdown
|
|
17428
|
+
${PROJECT_INDEX_TEMPLATE.trimEnd()}
|
|
17429
|
+
\`\`\`
|
|
17430
|
+
|
|
17431
|
+
Subindex (\`<partition>/index/**/*.md\`, excluding the main index):
|
|
17432
|
+
|
|
17433
|
+
\`\`\`markdown
|
|
17434
|
+
${PROJECT_SUBINDEX_TEMPLATE.trimEnd()}
|
|
17435
|
+
\`\`\`
|
|
17436
|
+
|
|
17437
|
+
General rules:
|
|
17438
|
+
|
|
17439
|
+
- Index every non-ignored path in scope unless a directory is large or low-value — then one directory line only.
|
|
17440
|
+
- Generic/config files: \`Ditto\`. Similar files: one grouped bullet.
|
|
17441
|
+
- Link each subindex from the main tree; keep the main index must-know navigation, not a full dump of every package detail.
|
|
17442
|
+
- Omit build/cache/dependency directories unless relevant. Document ignored paths only when agents need them.
|
|
17443
|
+
- Brain documents and layout belong in catalogs, not codebase indexes.
|
|
17444
|
+
- Follow index shapes when seeding; never freehand your own structure.
|
|
17445
|
+
|
|
17446
|
+
|
|
17447
|
+
### Partition Catalogs
|
|
17448
|
+
|
|
17449
|
+
Maintain one \`catalog.md\` per partition, updated whenever freeform content or layout changes. The catalog is an agent-maintained map of a partition's brain root. If a specific folder grows large, you may create a sub-catalog and link from main catalog.
|
|
17450
|
+
|
|
17451
|
+
- Catalog that partition's Brain only: no repository source files, project \`index/\`, or other partitions' paths.
|
|
17452
|
+
- Every freeform document entry requires \`Description\` and \`Read If\`. Partition root \`operator.md\` and \`catalog.md\` entries use \`Read If: Auto-injected\`; non-root proceed as normal.
|
|
17453
|
+
- Group similar entries, use \`Ditto\` where obvious, and list large or low-value directories as a single entry.
|
|
17454
|
+
- For an artifact-backed skill folder, catalog only its entry file (e.g. \`powerpoint-builder/SKILL.md\`), not the folder or individual supporting artifacts. Similar for other larger folders. Use few sub-catalogs only where appropriate; but prefer to keep brain lean and self-contained.
|
|
17455
|
+
- Follow this exact shape; remove seed instructions, placeholders, and example content from finished catalogs.
|
|
17456
|
+
|
|
17457
|
+
\`\`\`markdown
|
|
17458
|
+
${CATALOG_TEMPLATE.trimEnd()}
|
|
17459
|
+
\`\`\`
|
|
17460
|
+
|
|
17461
|
+
### Freeform Brain
|
|
17462
|
+
|
|
17463
|
+
Proactively preserve detailed knowledge in focused, cataloged documents. Suggested organization:
|
|
17464
|
+
|
|
17465
|
+
- \`specs/\` — contracts, invariants, design decisions, requirements, expected behavior, documents code cannot own. Organized by feature, module, or system. Organize via subdirectories where appropriate.
|
|
17466
|
+
- \`guides/\` — reusable library, SDK, API, harness, and integration knowledge, including non-obvious and reusable findings from source exploration that will be used again. Create and record comprehensive guides, not one-off searches.
|
|
17467
|
+
- \`product/\` — user-established product intent, business vision, positioning, marketing, direction, and more, separate from implementation contracts.
|
|
17468
|
+
- Other documents and groupings you see fit. \`workflows/\`, \`research/\`, \`promo/\`, \`plans/\`, etc.
|
|
17469
|
+
|
|
17470
|
+
Freeform can include supporting code and artifacts, not just Markdown. Scripts, instructions, workflows, entire skill packages or repos can live inside the brain. Keep documents cohesive: extend it for the same concern, create another for a different concern, and split or consolidate when needed. Do not give into inertia, but do not neurotically refactor after every change. Update the catalog when content or scope changes.
|
|
17471
|
+
|
|
17472
|
+
**User-authored documents:** Certain instructions, workflows, or documents may be user authored or controlled; mark clearly if so, and do not change without user intent.
|
|
17473
|
+
|
|
17474
|
+
**Cold starts:** After Operator is added to an existing project, the brain may hold little more than instructions, catalogs, and indexes. Still create small, reasonably scoped specs for features/systems you actually work on. Document even if the brain is new. Do not skip writing because the brain is empty, and do not invent, infer, or pad requirements to make a document feel complete. Do not give into inertia. Greenfield projects are not cold starts; document as you build.
|
|
17475
|
+
|
|
17476
|
+
- **DO** proactively document in the freeform brain.
|
|
17477
|
+
- **DO** create a new spec when the work changes concern. Do not grow the first-feature spec into a catch-all contract.
|
|
17478
|
+
- **DO** update a spec only when the documented contract, invariant, or non-obvious decision changed. If existing clauses still hold, leave it. Naturally rewrite sentences instead of adding caveat or explanation paragraphs.
|
|
17479
|
+
- **DO** delete obsolete documentation after removing or simplifying features rather than replacing with commentary, caveats, or explanations. Document historical detail only if it's actually important.
|
|
17480
|
+
- **DO NOT** restate implementation details, inventory artifacts, or write file-by-file walkthroughs outside the Project Index. Concise purpose, architecture, and working-context overviews belong in \`operator.md\`, even when established from code.
|
|
17481
|
+
- **DO** preserve contracts, requirements, invariants, conventions, and other durable knowledge the code alone cannot convey.
|
|
17482
|
+
- **DO** keep the Partition Catalog in sync when freeform structure changes.
|
|
17483
|
+
|
|
17484
|
+
Examples — record brain entries in scenarios like these:
|
|
17485
|
+
|
|
17486
|
+
<example>
|
|
17487
|
+
- Durable contract, invariant, or convention the code does not make obvious (module, feature, or cross-cutting) → write or update a specification. If no single owner, use a shared architecture note.
|
|
17488
|
+
- User- or agent-defined decision, convention, or standard that should outlive this session → record it in the spec or work-area document that will enforce it. Do not leave it only in chat.
|
|
17489
|
+
- Deep dive into unfamiliar libraries, APIs, subsystems, or a cloned third-party tree that future work will reuse → write research notes or a focused guide. Add a private subindex if the source is cloned.
|
|
17490
|
+
- Integrating an external library, SDK, or product with non-obvious usage and no local notes → write an integration guide.
|
|
17491
|
+
- Trivial implementation changes, disposable exploration results, or guidance limited to the current task → do not add documentation unless an existing statement becomes outdated. Preserve lasting decisions even when stated or discovered only once. If long-term value is uncertain, ask the user.
|
|
17492
|
+
</example>
|
|
17493
|
+
|
|
17494
|
+
</operator-guidance>`;
|
|
17495
|
+
var PREAMBLE_TENETS2 = `<operator-tenets version="2.0">
|
|
17496
|
+
## **REMEMBER: Core Tenets**
|
|
17497
|
+
|
|
17498
|
+
<important>
|
|
17499
|
+
- **Run the memory-aware loop.** Consult relevant brain docs before you build; update it after you learn. Do not build from zero while a brain exists; do not leave durable knowledge unrecorded.
|
|
17500
|
+
- **Documents are truth and knowledge.** Read matching documents before every task. Update when details changes. Explore progressively. Do not default to reading everything.
|
|
17501
|
+
- **Persist durable, reusable knowledge.** Your context is ephemeral. You WILL forget everything after this session ends. Proactively maintain essential context: specs, decisions, guides, rules, findings, etc. in their canonical homes. Do not record task-local guidance or findings with no future usefulness. Permanent rules or definitely useful findings may be recorded in appropriate locations. If uncertain about long-term value, ask user whether to record.
|
|
17502
|
+
- **Keep memory current and lean.** Update changed contracts, resolve completed plans, and remove obsolete content without duplicating explanations or restating implementation. Outside of essential context or overviews, do not summarize or restate the code. Do not record paragraphs for minor tweaks. No edit sprawl; one home. Update naturally; state what is true now; no mentioning historical detail unless useful.
|
|
17503
|
+
</important>
|
|
17504
|
+
|
|
17505
|
+
**You must remember these tenets and apply them while you work.**
|
|
17506
|
+
</operator-tenets>`;
|
|
17507
|
+
|
|
17347
17508
|
// ../core/src/preamble.ts
|
|
17348
17509
|
var SHARED_ROOT = ".operator-shared";
|
|
17349
17510
|
var PRIVATE_ROOT = ".operator";
|
|
17350
17511
|
var USER_INSTRUCTIONS_PATH = "~/.operator/user/operator.md";
|
|
17351
17512
|
var USER_CATALOG_PATH = "~/.operator/user/catalog.md";
|
|
17352
17513
|
function renderPreamble(memory) {
|
|
17514
|
+
const { PREAMBLE_PROMPT, PREAMBLE_TENETS } = selectPreambleVersion() === "2.0" ? exports_preamble_v2 : exports_preamble_v1;
|
|
17353
17515
|
if (!memory.shared.ok || !memory.user.ok || !memory.private.ok) {
|
|
17354
17516
|
return {
|
|
17355
17517
|
content: `${PREAMBLE_PROMPT}
|
|
@@ -17425,12 +17587,19 @@ ${status("Shared", memory.shared)}
|
|
|
17425
17587
|
${status("User", memory.user)}
|
|
17426
17588
|
${status("Private", memory.private)}
|
|
17427
17589
|
|
|
17428
|
-
IMPORTANT: You MUST
|
|
17590
|
+
IMPORTANT: You MUST resolve Operator memory loading before proceeding with the user's requested work. User and project instructions were not loaded.
|
|
17591
|
+
|
|
17592
|
+
1. Run \`operator-helper version\`. If an update is available, run \`operator-helper upgrade\` before continuing.
|
|
17593
|
+
2. Run \`operator-helper memory check\` from the affected project directory to obtain current loading results.
|
|
17594
|
+
3. Repair only the reported load failures. Preserve existing content, do not initialize absent partitions, and do not reset or replace the Brain. If a repair requires deleting content, reconstructing instructions, or choosing between ambiguous fixes, stop and ask the user for guidance.
|
|
17595
|
+
4. Rerun \`operator-helper memory check\` after repairs. Resolve any additional load failures it reveals until the check succeeds or a concrete blocker prevents further progress.
|
|
17429
17596
|
|
|
17430
|
-
|
|
17597
|
+
\`operator-helper\` is the globally installed Operator CLI (npm package \`@aerovato/operator-helper\`), not a project dependency.
|
|
17431
17598
|
|
|
17432
|
-
- If
|
|
17433
|
-
- If
|
|
17599
|
+
- If Helper cannot start, install or repair its global installation and retry the failed command.
|
|
17600
|
+
- If the version check or upgrade fails, diagnose the failure and retry.
|
|
17601
|
+
- If recovery is blocked, report the failing path or operation, the cause, and what is needed to continue. Do not proceed with the original task.
|
|
17602
|
+
- When validation succeeds, tell the user that loading is repaired and ask them to start a new session and resubmit their original request so the complete preamble is loaded. Do not resume the original task in this diagnostic-only session.
|
|
17434
17603
|
</operator-diagnostic>`;
|
|
17435
17604
|
}
|
|
17436
17605
|
function renderInstructions(memory) {
|
|
@@ -18144,4 +18313,4 @@ var main = gen2(function* () {
|
|
|
18144
18313
|
}).pipe(provide4(LiveLayers));
|
|
18145
18314
|
runMain2(main);
|
|
18146
18315
|
|
|
18147
|
-
//# debugId=
|
|
18316
|
+
//# debugId=9837A2D60E03644D64756E2164756E21
|