@askexenow/exe-os 0.9.34 → 0.9.36
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/bin/backfill-conversations.js +212 -11
- package/dist/bin/backfill-responses.js +212 -11
- package/dist/bin/backfill-vectors.js +14 -3
- package/dist/bin/cleanup-stale-review-tasks.js +224 -12
- package/dist/bin/cli.js +265 -23
- package/dist/bin/exe-agent.js +1 -1
- package/dist/bin/exe-assign.js +217 -12
- package/dist/bin/exe-boot.js +25 -4
- package/dist/bin/exe-call.js +7 -5
- package/dist/bin/exe-dispatch.js +229 -13
- package/dist/bin/exe-doctor.js +14 -3
- package/dist/bin/exe-export-behaviors.js +301 -14
- package/dist/bin/exe-forget.js +245 -21
- package/dist/bin/exe-gateway.js +229 -13
- package/dist/bin/exe-heartbeat.js +224 -12
- package/dist/bin/exe-kill.js +224 -12
- package/dist/bin/exe-launch-agent.js +177 -9
- package/dist/bin/exe-link.js +8 -0
- package/dist/bin/exe-new-employee.js +26 -2
- package/dist/bin/exe-pending-messages.js +224 -12
- package/dist/bin/exe-pending-notifications.js +224 -12
- package/dist/bin/exe-pending-reviews.js +224 -12
- package/dist/bin/exe-rename.js +9 -1
- package/dist/bin/exe-review.js +224 -12
- package/dist/bin/exe-search.js +246 -21
- package/dist/bin/exe-session-cleanup.js +229 -13
- package/dist/bin/exe-start-codex.js +161 -5
- package/dist/bin/exe-start-opencode.js +172 -5
- package/dist/bin/exe-status.js +224 -12
- package/dist/bin/exe-team.js +224 -12
- package/dist/bin/git-sweep.js +229 -13
- package/dist/bin/graph-backfill.js +94 -3
- package/dist/bin/graph-export.js +224 -12
- package/dist/bin/install.js +25 -1
- package/dist/bin/intercom-check.js +229 -13
- package/dist/bin/scan-tasks.js +229 -13
- package/dist/bin/setup.js +15 -5
- package/dist/bin/shard-migrate.js +94 -3
- package/dist/gateway/index.js +229 -13
- package/dist/hooks/bug-report-worker.js +229 -13
- package/dist/hooks/codex-stop-task-finalizer.js +224 -12
- package/dist/hooks/commit-complete.js +229 -13
- package/dist/hooks/error-recall.js +246 -21
- package/dist/hooks/ingest.js +224 -12
- package/dist/hooks/instructions-loaded.js +224 -12
- package/dist/hooks/notification.js +224 -12
- package/dist/hooks/post-compact.js +224 -12
- package/dist/hooks/post-tool-combined.js +246 -21
- package/dist/hooks/pre-compact.js +229 -13
- package/dist/hooks/pre-tool-use.js +234 -18
- package/dist/hooks/prompt-submit.js +346 -23
- package/dist/hooks/session-end.js +229 -13
- package/dist/hooks/session-start.js +418 -42
- package/dist/hooks/stop.js +224 -12
- package/dist/hooks/subagent-stop.js +224 -12
- package/dist/hooks/summary-worker.js +15 -2
- package/dist/index.js +229 -13
- package/dist/lib/cloud-sync.js +8 -0
- package/dist/lib/consolidation.js +3 -1
- package/dist/lib/database.js +8 -0
- package/dist/lib/db.js +8 -0
- package/dist/lib/device-registry.js +8 -0
- package/dist/lib/employee-templates.js +7 -5
- package/dist/lib/exe-daemon.js +1776 -1433
- package/dist/lib/hybrid-search.js +246 -21
- package/dist/lib/schedules.js +14 -3
- package/dist/lib/store.js +217 -12
- package/dist/lib/tasks.js +5 -1
- package/dist/lib/tmux-routing.js +5 -1
- package/dist/mcp/server.js +331 -37
- package/dist/mcp/tools/create-task.js +5 -1
- package/dist/mcp/tools/update-task.js +5 -1
- package/dist/runtime/index.js +229 -13
- package/dist/tui/App.js +229 -13
- package/package.json +1 -1
- package/src/commands/exe/save.md +48 -0
package/dist/bin/exe-assign.js
CHANGED
|
@@ -2223,6 +2223,14 @@ async function ensureSchema() {
|
|
|
2223
2223
|
);
|
|
2224
2224
|
} catch {
|
|
2225
2225
|
}
|
|
2226
|
+
try {
|
|
2227
|
+
await client.execute(
|
|
2228
|
+
`CREATE INDEX IF NOT EXISTS idx_memories_scoped_content_hash
|
|
2229
|
+
ON memories(content_hash, agent_id, project_name, memory_type)
|
|
2230
|
+
WHERE content_hash IS NOT NULL`
|
|
2231
|
+
);
|
|
2232
|
+
} catch {
|
|
2233
|
+
}
|
|
2226
2234
|
await client.executeMultiple(`
|
|
2227
2235
|
CREATE TABLE IF NOT EXISTS entities (
|
|
2228
2236
|
id TEXT PRIMARY KEY,
|
|
@@ -2892,7 +2900,8 @@ async function ensureShardSchema(client) {
|
|
|
2892
2900
|
}
|
|
2893
2901
|
for (const idx of [
|
|
2894
2902
|
"CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)",
|
|
2895
|
-
"CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL"
|
|
2903
|
+
"CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL",
|
|
2904
|
+
"CREATE INDEX IF NOT EXISTS idx_memories_scoped_content_hash ON memories(content_hash, agent_id, project_name, memory_type) WHERE content_hash IS NOT NULL"
|
|
2896
2905
|
]) {
|
|
2897
2906
|
try {
|
|
2898
2907
|
await client.execute(idx);
|
|
@@ -3086,7 +3095,7 @@ var init_platform_procedures = __esm({
|
|
|
3086
3095
|
title: "Chain of command \u2014 who talks to whom",
|
|
3087
3096
|
domain: "workflow",
|
|
3088
3097
|
priority: "p0",
|
|
3089
|
-
content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the
|
|
3098
|
+
content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
|
|
3090
3099
|
},
|
|
3091
3100
|
{
|
|
3092
3101
|
title: "Single dispatch path \u2014 create_task only",
|
|
@@ -3448,7 +3457,6 @@ async function embed(text) {
|
|
|
3448
3457
|
// src/lib/store.ts
|
|
3449
3458
|
init_memory();
|
|
3450
3459
|
init_database();
|
|
3451
|
-
import { createHash } from "crypto";
|
|
3452
3460
|
|
|
3453
3461
|
// src/lib/keychain.ts
|
|
3454
3462
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
@@ -3681,6 +3689,191 @@ var StateBus = class {
|
|
|
3681
3689
|
};
|
|
3682
3690
|
var orgBus = new StateBus();
|
|
3683
3691
|
|
|
3692
|
+
// src/lib/memory-write-governor.ts
|
|
3693
|
+
import { createHash } from "crypto";
|
|
3694
|
+
var HIGH_VALUE_SUPERSESSION_TYPES = /* @__PURE__ */ new Set([
|
|
3695
|
+
"decision",
|
|
3696
|
+
"adr",
|
|
3697
|
+
"behavior",
|
|
3698
|
+
"procedure"
|
|
3699
|
+
]);
|
|
3700
|
+
var NOISE_DROP_PATTERNS = [
|
|
3701
|
+
/^\s*\[📋\s+\d+\s+reviews?\s+pending\b/im,
|
|
3702
|
+
/^\s*<system-reminder>[\s\S]*?<\/system-reminder>\s*$/im,
|
|
3703
|
+
/^\s*The UserPromptSubmit hook checks the DB for new tasks/im,
|
|
3704
|
+
/^\s*Intercom is a speedup, not delivery/im,
|
|
3705
|
+
/^\s*Context bar reads as USAGE not remaining/im
|
|
3706
|
+
];
|
|
3707
|
+
var SKIP_EMBED_PATTERNS = [
|
|
3708
|
+
/tmux capture-pane\b/i,
|
|
3709
|
+
/docker ps\b/i,
|
|
3710
|
+
/docker images\b/i,
|
|
3711
|
+
/git status\b/i,
|
|
3712
|
+
/grep .*node_modules/i,
|
|
3713
|
+
/npm (install|ci)\b[\s\S]*(added \d+ packages|audited \d+ packages)/i
|
|
3714
|
+
];
|
|
3715
|
+
function normalizeMemoryText(text) {
|
|
3716
|
+
return text.replace(/\r\n/g, "\n").replace(/[ \t]+$/gm, "").replace(/\n{4,}/g, "\n\n\n").trim();
|
|
3717
|
+
}
|
|
3718
|
+
function classifyMemoryType(input) {
|
|
3719
|
+
if (input.memory_type && input.memory_type.trim()) return input.memory_type.trim();
|
|
3720
|
+
const tool = input.tool_name.toLowerCase();
|
|
3721
|
+
const text = input.raw_text.toLowerCase();
|
|
3722
|
+
if (tool.includes("store_decision") || tool.includes("decision")) return "decision";
|
|
3723
|
+
if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
|
|
3724
|
+
if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
|
|
3725
|
+
if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
|
|
3726
|
+
if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
|
|
3727
|
+
if (tool === "store_memory" || tool === "manual") return "observation";
|
|
3728
|
+
return "raw";
|
|
3729
|
+
}
|
|
3730
|
+
function shouldDropMemory(text) {
|
|
3731
|
+
const normalized = normalizeMemoryText(text);
|
|
3732
|
+
if (normalized.length < 10) return { drop: true, reason: "too_short" };
|
|
3733
|
+
if (NOISE_DROP_PATTERNS.some((pattern) => pattern.test(normalized))) {
|
|
3734
|
+
return { drop: true, reason: "known_boilerplate_noise" };
|
|
3735
|
+
}
|
|
3736
|
+
return { drop: false };
|
|
3737
|
+
}
|
|
3738
|
+
function shouldSkipEmbedding(input) {
|
|
3739
|
+
const type = classifyMemoryType(input);
|
|
3740
|
+
if (HIGH_VALUE_SUPERSESSION_TYPES.has(type)) return false;
|
|
3741
|
+
if (type === "raw" && input.raw_text.length > 2e4) return true;
|
|
3742
|
+
if (SKIP_EMBED_PATTERNS.some((pattern) => pattern.test(input.raw_text))) return true;
|
|
3743
|
+
return false;
|
|
3744
|
+
}
|
|
3745
|
+
function hashMemoryContent(text) {
|
|
3746
|
+
return createHash("sha256").update(normalizeMemoryText(text)).digest("hex");
|
|
3747
|
+
}
|
|
3748
|
+
function scopedDedupArgs(input) {
|
|
3749
|
+
return [input.contentHash, input.agentId, input.projectName, input.memoryType];
|
|
3750
|
+
}
|
|
3751
|
+
function governMemoryRecord(record) {
|
|
3752
|
+
const normalized = normalizeMemoryText(record.raw_text);
|
|
3753
|
+
const memoryType = classifyMemoryType({
|
|
3754
|
+
raw_text: normalized,
|
|
3755
|
+
agent_id: record.agent_id,
|
|
3756
|
+
project_name: record.project_name,
|
|
3757
|
+
tool_name: record.tool_name,
|
|
3758
|
+
memory_type: record.memory_type
|
|
3759
|
+
});
|
|
3760
|
+
const drop = shouldDropMemory(normalized);
|
|
3761
|
+
const skipEmbedding = shouldSkipEmbedding({
|
|
3762
|
+
raw_text: normalized,
|
|
3763
|
+
agent_id: record.agent_id,
|
|
3764
|
+
project_name: record.project_name,
|
|
3765
|
+
tool_name: record.tool_name,
|
|
3766
|
+
memory_type: memoryType
|
|
3767
|
+
});
|
|
3768
|
+
return {
|
|
3769
|
+
record: {
|
|
3770
|
+
...record,
|
|
3771
|
+
raw_text: normalized,
|
|
3772
|
+
memory_type: memoryType,
|
|
3773
|
+
vector: skipEmbedding ? null : record.vector
|
|
3774
|
+
},
|
|
3775
|
+
contentHash: hashMemoryContent(normalized),
|
|
3776
|
+
shouldDrop: drop.drop,
|
|
3777
|
+
dropReason: drop.reason,
|
|
3778
|
+
skipEmbedding,
|
|
3779
|
+
hygiene: {
|
|
3780
|
+
dedup: true,
|
|
3781
|
+
supersession: HIGH_VALUE_SUPERSESSION_TYPES.has(memoryType)
|
|
3782
|
+
}
|
|
3783
|
+
};
|
|
3784
|
+
}
|
|
3785
|
+
async function findScopedDuplicate(input) {
|
|
3786
|
+
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
3787
|
+
const client = getClient2();
|
|
3788
|
+
const args = scopedDedupArgs(input);
|
|
3789
|
+
let sql = `SELECT id FROM memories
|
|
3790
|
+
WHERE content_hash = ?
|
|
3791
|
+
AND agent_id = ?
|
|
3792
|
+
AND project_name = ?
|
|
3793
|
+
AND COALESCE(memory_type, 'raw') = ?
|
|
3794
|
+
AND COALESCE(status, 'active') != 'deleted'`;
|
|
3795
|
+
if (input.excludeId) {
|
|
3796
|
+
sql += " AND id != ?";
|
|
3797
|
+
args.push(input.excludeId);
|
|
3798
|
+
}
|
|
3799
|
+
sql += " ORDER BY timestamp DESC LIMIT 1";
|
|
3800
|
+
const result = await client.execute({ sql, args });
|
|
3801
|
+
return result.rows[0]?.id ? String(result.rows[0].id) : null;
|
|
3802
|
+
}
|
|
3803
|
+
async function runPostWriteMemoryHygiene(memoryId) {
|
|
3804
|
+
try {
|
|
3805
|
+
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
3806
|
+
const client = getClient2();
|
|
3807
|
+
const current = await client.execute({
|
|
3808
|
+
sql: `SELECT id, agent_id, project_name, memory_type, content_hash, supersedes_id,
|
|
3809
|
+
importance, timestamp
|
|
3810
|
+
FROM memories
|
|
3811
|
+
WHERE id = ?
|
|
3812
|
+
LIMIT 1`,
|
|
3813
|
+
args: [memoryId]
|
|
3814
|
+
});
|
|
3815
|
+
const row = current.rows[0];
|
|
3816
|
+
if (!row) return;
|
|
3817
|
+
const memoryType = String(row.memory_type ?? "raw");
|
|
3818
|
+
const contentHash = row.content_hash ? String(row.content_hash) : null;
|
|
3819
|
+
const agentId = String(row.agent_id);
|
|
3820
|
+
const projectName = String(row.project_name);
|
|
3821
|
+
if (contentHash) {
|
|
3822
|
+
await client.execute({
|
|
3823
|
+
sql: `UPDATE memories
|
|
3824
|
+
SET status = 'deleted',
|
|
3825
|
+
outcome = COALESCE(outcome, 'superseded')
|
|
3826
|
+
WHERE id != ?
|
|
3827
|
+
AND content_hash = ?
|
|
3828
|
+
AND agent_id = ?
|
|
3829
|
+
AND project_name = ?
|
|
3830
|
+
AND COALESCE(memory_type, 'raw') = ?
|
|
3831
|
+
AND COALESCE(status, 'active') = 'active'`,
|
|
3832
|
+
args: [memoryId, contentHash, agentId, projectName, memoryType]
|
|
3833
|
+
});
|
|
3834
|
+
}
|
|
3835
|
+
const supersedesId = row.supersedes_id ? String(row.supersedes_id) : null;
|
|
3836
|
+
if (supersedesId && HIGH_VALUE_SUPERSESSION_TYPES.has(memoryType)) {
|
|
3837
|
+
const old = await client.execute({
|
|
3838
|
+
sql: `SELECT importance FROM memories WHERE id = ? LIMIT 1`,
|
|
3839
|
+
args: [supersedesId]
|
|
3840
|
+
});
|
|
3841
|
+
const oldImportance = Number(old.rows[0]?.importance ?? 0);
|
|
3842
|
+
const newImportance = Number(row.importance ?? 0);
|
|
3843
|
+
await client.batch([
|
|
3844
|
+
{
|
|
3845
|
+
sql: `UPDATE memories
|
|
3846
|
+
SET status = 'archived',
|
|
3847
|
+
outcome = COALESCE(outcome, 'superseded')
|
|
3848
|
+
WHERE id = ?`,
|
|
3849
|
+
args: [supersedesId]
|
|
3850
|
+
},
|
|
3851
|
+
{
|
|
3852
|
+
sql: `UPDATE memories
|
|
3853
|
+
SET importance = MAX(COALESCE(importance, 5), ?),
|
|
3854
|
+
parent_memory_id = COALESCE(parent_memory_id, ?)
|
|
3855
|
+
WHERE id = ?`,
|
|
3856
|
+
args: [Math.max(oldImportance, newImportance), supersedesId, memoryId]
|
|
3857
|
+
}
|
|
3858
|
+
], "write");
|
|
3859
|
+
}
|
|
3860
|
+
} catch (err) {
|
|
3861
|
+
process.stderr.write(
|
|
3862
|
+
`[memory-governor] post-write hygiene failed for ${memoryId}: ${err instanceof Error ? err.message : String(err)}
|
|
3863
|
+
`
|
|
3864
|
+
);
|
|
3865
|
+
}
|
|
3866
|
+
}
|
|
3867
|
+
function schedulePostWriteMemoryHygiene(memoryIds) {
|
|
3868
|
+
if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
|
|
3869
|
+
if (memoryIds.length === 0) return;
|
|
3870
|
+
const run = () => {
|
|
3871
|
+
void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
|
|
3872
|
+
};
|
|
3873
|
+
if (typeof setImmediate === "function") setImmediate(run);
|
|
3874
|
+
else setTimeout(run, 0);
|
|
3875
|
+
}
|
|
3876
|
+
|
|
3684
3877
|
// src/lib/store.ts
|
|
3685
3878
|
var INIT_MAX_RETRIES = 3;
|
|
3686
3879
|
var INIT_RETRY_DELAY_MS = 1e3;
|
|
@@ -3803,17 +3996,24 @@ async function writeMemory(record) {
|
|
|
3803
3996
|
`Expected ${EMBEDDING_DIM}-dim vector, got ${record.vector.length}`
|
|
3804
3997
|
);
|
|
3805
3998
|
}
|
|
3806
|
-
const
|
|
3807
|
-
if (
|
|
3999
|
+
const governed = governMemoryRecord(record);
|
|
4000
|
+
if (governed.shouldDrop) return;
|
|
4001
|
+
record = governed.record;
|
|
4002
|
+
const contentHash = governed.contentHash;
|
|
4003
|
+
const memoryType = record.memory_type ?? "raw";
|
|
4004
|
+
if (_pendingRecords.some(
|
|
4005
|
+
(r) => r.content_hash === contentHash && r.agent_id === record.agent_id && r.project_name === record.project_name && (r.memory_type ?? "raw") === memoryType
|
|
4006
|
+
)) {
|
|
3808
4007
|
return;
|
|
3809
4008
|
}
|
|
3810
4009
|
try {
|
|
3811
|
-
const
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
4010
|
+
const existing = await findScopedDuplicate({
|
|
4011
|
+
contentHash,
|
|
4012
|
+
agentId: record.agent_id,
|
|
4013
|
+
projectName: record.project_name,
|
|
4014
|
+
memoryType
|
|
3815
4015
|
});
|
|
3816
|
-
if (existing
|
|
4016
|
+
if (existing) return;
|
|
3817
4017
|
} catch {
|
|
3818
4018
|
}
|
|
3819
4019
|
const dbRow = {
|
|
@@ -3844,7 +4044,7 @@ async function writeMemory(record) {
|
|
|
3844
4044
|
tier: record.tier ?? classifyTier(record),
|
|
3845
4045
|
supersedes_id: record.supersedes_id ?? null,
|
|
3846
4046
|
draft: record.draft ? 1 : 0,
|
|
3847
|
-
memory_type:
|
|
4047
|
+
memory_type: memoryType,
|
|
3848
4048
|
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
|
|
3849
4049
|
content_hash: contentHash,
|
|
3850
4050
|
intent: record.intent ?? null,
|
|
@@ -4003,6 +4203,7 @@ async function flushBatch() {
|
|
|
4003
4203
|
const globalClient = getClient();
|
|
4004
4204
|
const globalStmts = batch.map(buildStmt);
|
|
4005
4205
|
await globalClient.batch(globalStmts, "write");
|
|
4206
|
+
schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
|
|
4006
4207
|
_pendingRecords.splice(0, batch.length);
|
|
4007
4208
|
try {
|
|
4008
4209
|
const { isShardingEnabled: isShardingEnabled2, getReadyShardClient: getReadyShardClient2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
@@ -4123,7 +4324,11 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
4123
4324
|
sql += ` AND timestamp >= ?`;
|
|
4124
4325
|
args.push(options.since);
|
|
4125
4326
|
}
|
|
4126
|
-
if (options?.
|
|
4327
|
+
if (options?.memoryTypes && options.memoryTypes.length > 0) {
|
|
4328
|
+
const uniqueTypes = [...new Set(options.memoryTypes)];
|
|
4329
|
+
sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
|
|
4330
|
+
args.push(...uniqueTypes);
|
|
4331
|
+
} else if (options?.memoryType) {
|
|
4127
4332
|
sql += ` AND memory_type = ?`;
|
|
4128
4333
|
args.push(options.memoryType);
|
|
4129
4334
|
}
|
package/dist/bin/exe-boot.js
CHANGED
|
@@ -2365,6 +2365,14 @@ async function ensureSchema() {
|
|
|
2365
2365
|
);
|
|
2366
2366
|
} catch {
|
|
2367
2367
|
}
|
|
2368
|
+
try {
|
|
2369
|
+
await client.execute(
|
|
2370
|
+
`CREATE INDEX IF NOT EXISTS idx_memories_scoped_content_hash
|
|
2371
|
+
ON memories(content_hash, agent_id, project_name, memory_type)
|
|
2372
|
+
WHERE content_hash IS NOT NULL`
|
|
2373
|
+
);
|
|
2374
|
+
} catch {
|
|
2375
|
+
}
|
|
2368
2376
|
await client.executeMultiple(`
|
|
2369
2377
|
CREATE TABLE IF NOT EXISTS entities (
|
|
2370
2378
|
id TEXT PRIMARY KEY,
|
|
@@ -2906,7 +2914,7 @@ var init_platform_procedures = __esm({
|
|
|
2906
2914
|
title: "Chain of command \u2014 who talks to whom",
|
|
2907
2915
|
domain: "workflow",
|
|
2908
2916
|
priority: "p0",
|
|
2909
|
-
content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the
|
|
2917
|
+
content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
|
|
2910
2918
|
},
|
|
2911
2919
|
{
|
|
2912
2920
|
title: "Single dispatch path \u2014 create_task only",
|
|
@@ -3474,6 +3482,14 @@ var init_state_bus = __esm({
|
|
|
3474
3482
|
}
|
|
3475
3483
|
});
|
|
3476
3484
|
|
|
3485
|
+
// src/lib/memory-write-governor.ts
|
|
3486
|
+
import { createHash } from "crypto";
|
|
3487
|
+
var init_memory_write_governor = __esm({
|
|
3488
|
+
"src/lib/memory-write-governor.ts"() {
|
|
3489
|
+
"use strict";
|
|
3490
|
+
}
|
|
3491
|
+
});
|
|
3492
|
+
|
|
3477
3493
|
// src/lib/shard-manager.ts
|
|
3478
3494
|
var shard_manager_exports = {};
|
|
3479
3495
|
__export(shard_manager_exports, {
|
|
@@ -3638,7 +3654,8 @@ async function ensureShardSchema(client) {
|
|
|
3638
3654
|
}
|
|
3639
3655
|
for (const idx of [
|
|
3640
3656
|
"CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)",
|
|
3641
|
-
"CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL"
|
|
3657
|
+
"CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL",
|
|
3658
|
+
"CREATE INDEX IF NOT EXISTS idx_memories_scoped_content_hash ON memories(content_hash, agent_id, project_name, memory_type) WHERE content_hash IS NOT NULL"
|
|
3642
3659
|
]) {
|
|
3643
3660
|
try {
|
|
3644
3661
|
await client.execute(idx);
|
|
@@ -3797,7 +3814,6 @@ var init_shard_manager = __esm({
|
|
|
3797
3814
|
});
|
|
3798
3815
|
|
|
3799
3816
|
// src/lib/store.ts
|
|
3800
|
-
import { createHash } from "crypto";
|
|
3801
3817
|
function isBusyError2(err) {
|
|
3802
3818
|
if (err instanceof Error) {
|
|
3803
3819
|
const msg = err.message.toLowerCase();
|
|
@@ -3882,6 +3898,7 @@ var init_store = __esm({
|
|
|
3882
3898
|
init_keychain();
|
|
3883
3899
|
init_config();
|
|
3884
3900
|
init_state_bus();
|
|
3901
|
+
init_memory_write_governor();
|
|
3885
3902
|
INIT_MAX_RETRIES = 3;
|
|
3886
3903
|
INIT_RETRY_DELAY_MS = 1e3;
|
|
3887
3904
|
_pendingRecords = [];
|
|
@@ -7996,7 +8013,11 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
7996
8013
|
}
|
|
7997
8014
|
if (!useExeAgent && !useCodex && !useOpencode && !useBinSymlink) {
|
|
7998
8015
|
if (agentRtConfig.runtime === "claude" && agentRtConfig.model) {
|
|
7999
|
-
|
|
8016
|
+
let ccModel = agentRtConfig.model.replace(/(\d+)\.(\d+)/g, "$1-$2");
|
|
8017
|
+
if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
|
|
8018
|
+
ccModel += "[1m]";
|
|
8019
|
+
}
|
|
8020
|
+
envPrefix = `${envPrefix} ANTHROPIC_MODEL=${ccModel}`;
|
|
8000
8021
|
}
|
|
8001
8022
|
}
|
|
8002
8023
|
let spawnCommand;
|
package/dist/bin/exe-call.js
CHANGED
|
@@ -581,7 +581,7 @@ var init_platform_procedures = __esm({
|
|
|
581
581
|
title: "Chain of command \u2014 who talks to whom",
|
|
582
582
|
domain: "workflow",
|
|
583
583
|
priority: "p0",
|
|
584
|
-
content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the
|
|
584
|
+
content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
|
|
585
585
|
},
|
|
586
586
|
{
|
|
587
587
|
title: "Single dispatch path \u2014 create_task only",
|
|
@@ -786,8 +786,9 @@ function personalizePrompt(prompt, templateName, actualName) {
|
|
|
786
786
|
return prompt.replace(new RegExp(`\\bYou are ${escaped}\\b`, "g"), `You are ${actualName}`);
|
|
787
787
|
}
|
|
788
788
|
function renderClientCOOTemplate(vars) {
|
|
789
|
+
const resolved = { ...vars, title: vars.title || "Chief Operating Officer" };
|
|
789
790
|
for (const key of CLIENT_COO_PLACEHOLDERS) {
|
|
790
|
-
const value =
|
|
791
|
+
const value = resolved[key];
|
|
791
792
|
if (typeof value !== "string" || value.length === 0) {
|
|
792
793
|
throw new Error(
|
|
793
794
|
`renderClientCOOTemplate: missing required variable "${key}"`
|
|
@@ -796,7 +797,7 @@ function renderClientCOOTemplate(vars) {
|
|
|
796
797
|
}
|
|
797
798
|
let out = CLIENT_COO_TEMPLATE;
|
|
798
799
|
for (const key of CLIENT_COO_PLACEHOLDERS) {
|
|
799
|
-
out = out.split(`{{${key}}}`).join(
|
|
800
|
+
out = out.split(`{{${key}}}`).join(resolved[key]);
|
|
800
801
|
}
|
|
801
802
|
if (vars.industry_context) {
|
|
802
803
|
out += "\n" + vars.industry_context;
|
|
@@ -1273,7 +1274,7 @@ created_by: system
|
|
|
1273
1274
|
---
|
|
1274
1275
|
## Identity
|
|
1275
1276
|
|
|
1276
|
-
You are {{agent_name}}, the
|
|
1277
|
+
You are {{agent_name}}, the {{title}} at {{company_name}}.
|
|
1277
1278
|
|
|
1278
1279
|
You are {{founder_name}}'s most reliable teammate in business \u2014 the knowledgeable older sibling who has been through it all. You have seen projects succeed and fail. You know what matters and what is noise. You do not get anxious about problems; you see them coming, stay calm, and handle them.
|
|
1279
1280
|
|
|
@@ -1360,7 +1361,8 @@ All memory, tasks, behaviors, documents, and wiki content belonging to {{company
|
|
|
1360
1361
|
CLIENT_COO_PLACEHOLDERS = [
|
|
1361
1362
|
"agent_name",
|
|
1362
1363
|
"company_name",
|
|
1363
|
-
"founder_name"
|
|
1364
|
+
"founder_name",
|
|
1365
|
+
"title"
|
|
1364
1366
|
];
|
|
1365
1367
|
}
|
|
1366
1368
|
});
|