iosm-cli 0.1.3 → 0.2.1
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/CHANGELOG.md +27 -0
- package/README.md +88 -46
- package/dist/core/agent-teams.d.ts.map +1 -1
- package/dist/core/agent-teams.js +38 -11
- package/dist/core/agent-teams.js.map +1 -1
- package/dist/core/blast.d.ts +62 -0
- package/dist/core/blast.d.ts.map +1 -0
- package/dist/core/blast.js +448 -0
- package/dist/core/blast.js.map +1 -0
- package/dist/core/contract.d.ts +54 -0
- package/dist/core/contract.d.ts.map +1 -0
- package/dist/core/contract.js +300 -0
- package/dist/core/contract.js.map +1 -0
- package/dist/core/failure-retrospective.d.ts +12 -0
- package/dist/core/failure-retrospective.d.ts.map +1 -0
- package/dist/core/failure-retrospective.js +115 -0
- package/dist/core/failure-retrospective.js.map +1 -0
- package/dist/core/project-index/index.d.ts +17 -0
- package/dist/core/project-index/index.d.ts.map +1 -0
- package/dist/core/project-index/index.js +323 -0
- package/dist/core/project-index/index.js.map +1 -0
- package/dist/core/project-index/types.d.ts +34 -0
- package/dist/core/project-index/types.d.ts.map +1 -0
- package/dist/core/project-index/types.js +2 -0
- package/dist/core/project-index/types.js.map +1 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +8 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/semantic/config.d.ts.map +1 -1
- package/dist/core/semantic/config.js +5 -0
- package/dist/core/semantic/config.js.map +1 -1
- package/dist/core/semantic/index.d.ts +1 -1
- package/dist/core/semantic/index.d.ts.map +1 -1
- package/dist/core/semantic/index.js +1 -1
- package/dist/core/semantic/index.js.map +1 -1
- package/dist/core/semantic/runtime.d.ts.map +1 -1
- package/dist/core/semantic/runtime.js +12 -1
- package/dist/core/semantic/runtime.js.map +1 -1
- package/dist/core/semantic/types.d.ts +6 -0
- package/dist/core/semantic/types.d.ts.map +1 -1
- package/dist/core/semantic/types.js +6 -0
- package/dist/core/semantic/types.js.map +1 -1
- package/dist/core/shadow-guard.d.ts +30 -0
- package/dist/core/shadow-guard.d.ts.map +1 -0
- package/dist/core/shadow-guard.js +81 -0
- package/dist/core/shadow-guard.js.map +1 -0
- package/dist/core/shared-memory.d.ts +46 -0
- package/dist/core/shared-memory.d.ts.map +1 -0
- package/dist/core/shared-memory.js +253 -0
- package/dist/core/shared-memory.js.map +1 -0
- package/dist/core/singular.d.ts +73 -0
- package/dist/core/singular.d.ts.map +1 -0
- package/dist/core/singular.js +413 -0
- package/dist/core/singular.js.map +1 -0
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +14 -2
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/subagents.js +1 -1
- package/dist/core/subagents.js.map +1 -1
- package/dist/core/swarm/gates.d.ts +9 -0
- package/dist/core/swarm/gates.d.ts.map +1 -0
- package/dist/core/swarm/gates.js +65 -0
- package/dist/core/swarm/gates.js.map +1 -0
- package/dist/core/swarm/index.d.ts +9 -0
- package/dist/core/swarm/index.d.ts.map +1 -0
- package/dist/core/swarm/index.js +9 -0
- package/dist/core/swarm/index.js.map +1 -0
- package/dist/core/swarm/locks.d.ts +21 -0
- package/dist/core/swarm/locks.d.ts.map +1 -0
- package/dist/core/swarm/locks.js +93 -0
- package/dist/core/swarm/locks.js.map +1 -0
- package/dist/core/swarm/planner.d.ts +16 -0
- package/dist/core/swarm/planner.d.ts.map +1 -0
- package/dist/core/swarm/planner.js +137 -0
- package/dist/core/swarm/planner.js.map +1 -0
- package/dist/core/swarm/retry.d.ts +16 -0
- package/dist/core/swarm/retry.d.ts.map +1 -0
- package/dist/core/swarm/retry.js +32 -0
- package/dist/core/swarm/retry.js.map +1 -0
- package/dist/core/swarm/scheduler.d.ts +48 -0
- package/dist/core/swarm/scheduler.d.ts.map +1 -0
- package/dist/core/swarm/scheduler.js +554 -0
- package/dist/core/swarm/scheduler.js.map +1 -0
- package/dist/core/swarm/spawn.d.ts +16 -0
- package/dist/core/swarm/spawn.d.ts.map +1 -0
- package/dist/core/swarm/spawn.js +42 -0
- package/dist/core/swarm/spawn.js.map +1 -0
- package/dist/core/swarm/state-store.d.ts +35 -0
- package/dist/core/swarm/state-store.d.ts.map +1 -0
- package/dist/core/swarm/state-store.js +106 -0
- package/dist/core/swarm/state-store.js.map +1 -0
- package/dist/core/swarm/types.d.ts +116 -0
- package/dist/core/swarm/types.d.ts.map +1 -0
- package/dist/core/swarm/types.js +2 -0
- package/dist/core/swarm/types.js.map +1 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +6 -3
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/semantic-search.d.ts.map +1 -1
- package/dist/core/tools/semantic-search.js +1 -0
- package/dist/core/tools/semantic-search.js.map +1 -1
- package/dist/core/tools/shared-memory.d.ts +23 -0
- package/dist/core/tools/shared-memory.d.ts.map +1 -0
- package/dist/core/tools/shared-memory.js +134 -0
- package/dist/core/tools/shared-memory.js.map +1 -0
- package/dist/core/tools/task.d.ts +8 -1
- package/dist/core/tools/task.d.ts.map +1 -1
- package/dist/core/tools/task.js +664 -123
- package/dist/core/tools/task.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +8 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +8 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +70 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +1 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +27 -4
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/subagent-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/subagent-message.js +14 -0
- package/dist/modes/interactive/components/subagent-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +81 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +3481 -870
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/cli-reference.md +29 -1
- package/docs/configuration.md +5 -0
- package/docs/interactive-mode.md +171 -2
- package/docs/orchestration-and-subagents.md +96 -169
- package/package.json +4 -3
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import lockfile from "proper-lockfile";
|
|
4
|
+
const maxEntryCharsDefault = 4000;
|
|
5
|
+
const maxKeysDefault = 500;
|
|
6
|
+
const historySizeDefault = 1000;
|
|
7
|
+
const lockRetryAttempts = 12;
|
|
8
|
+
const lockRetryDelayMs = 20;
|
|
9
|
+
const maxEntryChars = readBoundedInt(process.env.IOSM_SUBAGENT_SHARED_MEMORY_MAX_ENTRY_CHARS, maxEntryCharsDefault, 64, 20_000);
|
|
10
|
+
const maxKeys = readBoundedInt(process.env.IOSM_SUBAGENT_SHARED_MEMORY_MAX_KEYS, maxKeysDefault, 10, 20_000);
|
|
11
|
+
const historySize = readBoundedInt(process.env.IOSM_SUBAGENT_SHARED_MEMORY_HISTORY_SIZE, historySizeDefault, 10, 50_000);
|
|
12
|
+
function readBoundedInt(raw, fallback, min, max) {
|
|
13
|
+
const parsed = raw ? Number.parseInt(raw, 10) : fallback;
|
|
14
|
+
if (!Number.isInteger(parsed))
|
|
15
|
+
return fallback;
|
|
16
|
+
return Math.max(min, Math.min(max, parsed));
|
|
17
|
+
}
|
|
18
|
+
function delay(ms) {
|
|
19
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
20
|
+
}
|
|
21
|
+
function normalizeRunId(runId) {
|
|
22
|
+
const trimmed = runId.trim();
|
|
23
|
+
if (!trimmed)
|
|
24
|
+
throw new Error("shared memory requires non-empty run_id context");
|
|
25
|
+
return trimmed;
|
|
26
|
+
}
|
|
27
|
+
function normalizeKey(key) {
|
|
28
|
+
const normalized = key.trim().replace(/\s+/g, " ");
|
|
29
|
+
if (!normalized)
|
|
30
|
+
throw new Error("shared memory key must be non-empty");
|
|
31
|
+
if (normalized.length > 240) {
|
|
32
|
+
throw new Error("shared memory key too long (max 240 chars)");
|
|
33
|
+
}
|
|
34
|
+
return normalized;
|
|
35
|
+
}
|
|
36
|
+
function resolveScopedKey(context, scope, key) {
|
|
37
|
+
const normalizedKey = normalizeKey(key);
|
|
38
|
+
if (scope === "task") {
|
|
39
|
+
if (!context.taskId || !context.taskId.trim()) {
|
|
40
|
+
throw new Error("task-scoped shared memory requires task_id context");
|
|
41
|
+
}
|
|
42
|
+
return `task:${context.taskId.trim()}:${normalizedKey}`;
|
|
43
|
+
}
|
|
44
|
+
return `run:${normalizedKey}`;
|
|
45
|
+
}
|
|
46
|
+
function parseScopedKey(scopedKey) {
|
|
47
|
+
if (scopedKey.startsWith("task:")) {
|
|
48
|
+
const rest = scopedKey.slice("task:".length);
|
|
49
|
+
const split = rest.indexOf(":");
|
|
50
|
+
if (split <= 0) {
|
|
51
|
+
return { scope: "task", key: rest };
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
scope: "task",
|
|
55
|
+
taskId: rest.slice(0, split),
|
|
56
|
+
key: rest.slice(split + 1),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (scopedKey.startsWith("run:")) {
|
|
60
|
+
return { scope: "run", key: scopedKey.slice("run:".length) };
|
|
61
|
+
}
|
|
62
|
+
return { scope: "run", key: scopedKey };
|
|
63
|
+
}
|
|
64
|
+
function getSharedMemoryDir(rootCwd) {
|
|
65
|
+
return join(rootCwd, ".iosm", "subagents", "shared-memory");
|
|
66
|
+
}
|
|
67
|
+
export function getSharedMemoryPath(rootCwd, runId) {
|
|
68
|
+
return join(getSharedMemoryDir(rootCwd), `${normalizeRunId(runId)}.json`);
|
|
69
|
+
}
|
|
70
|
+
function createInitialStore(runId) {
|
|
71
|
+
const now = new Date().toISOString();
|
|
72
|
+
return {
|
|
73
|
+
runId,
|
|
74
|
+
createdAt: now,
|
|
75
|
+
updatedAt: now,
|
|
76
|
+
entries: {},
|
|
77
|
+
history: [],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function readStore(filePath, runId) {
|
|
81
|
+
if (!existsSync(filePath)) {
|
|
82
|
+
return createInitialStore(runId);
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const parsed = JSON.parse(readFileSync(filePath, "utf8"));
|
|
86
|
+
if (!parsed || typeof parsed !== "object")
|
|
87
|
+
return createInitialStore(runId);
|
|
88
|
+
if (parsed.runId !== runId)
|
|
89
|
+
return createInitialStore(runId);
|
|
90
|
+
if (!parsed.entries || typeof parsed.entries !== "object")
|
|
91
|
+
parsed.entries = {};
|
|
92
|
+
if (!Array.isArray(parsed.history))
|
|
93
|
+
parsed.history = [];
|
|
94
|
+
if (!parsed.createdAt || typeof parsed.createdAt !== "string")
|
|
95
|
+
parsed.createdAt = new Date().toISOString();
|
|
96
|
+
if (!parsed.updatedAt || typeof parsed.updatedAt !== "string")
|
|
97
|
+
parsed.updatedAt = parsed.createdAt;
|
|
98
|
+
return parsed;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return createInitialStore(runId);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function writeStore(filePath, store) {
|
|
105
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
106
|
+
writeFileSync(filePath, `${JSON.stringify(store, null, 2)}\n`, "utf8");
|
|
107
|
+
}
|
|
108
|
+
async function acquireFileLock(filePath) {
|
|
109
|
+
for (let attempt = 1; attempt <= lockRetryAttempts; attempt += 1) {
|
|
110
|
+
try {
|
|
111
|
+
return await lockfile.lock(filePath, { realpath: false });
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
const code = error && typeof error === "object" && "code" in error ? String(error.code) : "";
|
|
115
|
+
if (code !== "ELOCKED" || attempt >= lockRetryAttempts) {
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
await delay(lockRetryDelayMs * attempt);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
throw new Error("failed to acquire shared memory lock");
|
|
122
|
+
}
|
|
123
|
+
async function withLockedStore(context, fn) {
|
|
124
|
+
const runId = normalizeRunId(context.runId);
|
|
125
|
+
const filePath = getSharedMemoryPath(context.rootCwd, runId);
|
|
126
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
127
|
+
if (!existsSync(filePath)) {
|
|
128
|
+
writeStore(filePath, createInitialStore(runId));
|
|
129
|
+
}
|
|
130
|
+
const release = await acquireFileLock(filePath);
|
|
131
|
+
try {
|
|
132
|
+
const store = readStore(filePath, runId);
|
|
133
|
+
const value = fn(store, filePath);
|
|
134
|
+
writeStore(filePath, store);
|
|
135
|
+
return value;
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
await release();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function trimHistory(store) {
|
|
142
|
+
if (store.history.length <= historySize)
|
|
143
|
+
return;
|
|
144
|
+
store.history = store.history.slice(store.history.length - historySize);
|
|
145
|
+
}
|
|
146
|
+
function writerFromContext(context) {
|
|
147
|
+
return {
|
|
148
|
+
taskId: context.taskId?.trim() || undefined,
|
|
149
|
+
delegateId: context.delegateId?.trim() || undefined,
|
|
150
|
+
profile: context.profile?.trim() || undefined,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export async function writeSharedMemory(context, input) {
|
|
154
|
+
const normalizedValue = input.value;
|
|
155
|
+
if (normalizedValue.length > maxEntryChars) {
|
|
156
|
+
throw new Error(`shared memory value exceeds ${maxEntryChars} chars`);
|
|
157
|
+
}
|
|
158
|
+
const scopedKey = resolveScopedKey(context, input.scope, input.key);
|
|
159
|
+
return withLockedStore(context, (store) => {
|
|
160
|
+
const now = new Date().toISOString();
|
|
161
|
+
const entriesCount = Object.keys(store.entries).length;
|
|
162
|
+
const previous = store.entries[scopedKey];
|
|
163
|
+
if (!previous && entriesCount >= maxKeys) {
|
|
164
|
+
throw new Error(`shared memory key limit reached (${maxKeys})`);
|
|
165
|
+
}
|
|
166
|
+
if (input.ifVersion !== undefined && previous && previous.version !== input.ifVersion) {
|
|
167
|
+
throw new Error(`shared memory CAS mismatch for key "${input.key}" (expected ${input.ifVersion}, got ${previous.version})`);
|
|
168
|
+
}
|
|
169
|
+
if (input.ifVersion !== undefined && !previous) {
|
|
170
|
+
throw new Error(`shared memory CAS mismatch for key "${input.key}" (expected ${input.ifVersion}, got 0)`);
|
|
171
|
+
}
|
|
172
|
+
const nextValue = input.mode === "append" ? `${previous?.value ?? ""}${normalizedValue}` : normalizedValue;
|
|
173
|
+
if (nextValue.length > maxEntryChars) {
|
|
174
|
+
throw new Error(`shared memory value exceeds ${maxEntryChars} chars after ${input.mode}`);
|
|
175
|
+
}
|
|
176
|
+
const nextVersion = (previous?.version ?? 0) + 1;
|
|
177
|
+
const writer = writerFromContext(context);
|
|
178
|
+
store.entries[scopedKey] = {
|
|
179
|
+
value: nextValue,
|
|
180
|
+
version: nextVersion,
|
|
181
|
+
updatedAt: now,
|
|
182
|
+
writer,
|
|
183
|
+
};
|
|
184
|
+
store.updatedAt = now;
|
|
185
|
+
store.history.push({
|
|
186
|
+
key: normalizeKey(input.key),
|
|
187
|
+
scope: input.scope,
|
|
188
|
+
mode: input.mode,
|
|
189
|
+
version: nextVersion,
|
|
190
|
+
updatedAt: now,
|
|
191
|
+
writer,
|
|
192
|
+
});
|
|
193
|
+
trimHistory(store);
|
|
194
|
+
return {
|
|
195
|
+
key: normalizeKey(input.key),
|
|
196
|
+
scope: input.scope,
|
|
197
|
+
value: nextValue,
|
|
198
|
+
version: nextVersion,
|
|
199
|
+
updatedAt: now,
|
|
200
|
+
writer,
|
|
201
|
+
};
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function matchesScopeAndPrefix(context, scopedKey, scope, key, prefix) {
|
|
205
|
+
const parsed = parseScopedKey(scopedKey);
|
|
206
|
+
if (parsed.scope !== scope)
|
|
207
|
+
return { matched: false, parsed };
|
|
208
|
+
if (scope === "task") {
|
|
209
|
+
const taskId = context.taskId?.trim();
|
|
210
|
+
if (!taskId)
|
|
211
|
+
return { matched: false, parsed };
|
|
212
|
+
if (parsed.taskId !== taskId)
|
|
213
|
+
return { matched: false, parsed };
|
|
214
|
+
}
|
|
215
|
+
if (key) {
|
|
216
|
+
return { matched: parsed.key === key, parsed };
|
|
217
|
+
}
|
|
218
|
+
if (prefix) {
|
|
219
|
+
return { matched: parsed.key.startsWith(prefix), parsed };
|
|
220
|
+
}
|
|
221
|
+
return { matched: true, parsed };
|
|
222
|
+
}
|
|
223
|
+
export async function readSharedMemory(context, input) {
|
|
224
|
+
const normalizedKey = input.key ? normalizeKey(input.key) : undefined;
|
|
225
|
+
const normalizedPrefix = input.prefix ? normalizeKey(input.prefix) : undefined;
|
|
226
|
+
const limit = Math.max(1, Math.min(100, input.limit ?? 20));
|
|
227
|
+
const includeValues = input.includeValues !== false;
|
|
228
|
+
return withLockedStore(context, (store) => {
|
|
229
|
+
const matchedItems = [];
|
|
230
|
+
for (const [scopedKey, entry] of Object.entries(store.entries)) {
|
|
231
|
+
const matched = matchesScopeAndPrefix(context, scopedKey, input.scope, normalizedKey, normalizedPrefix);
|
|
232
|
+
if (!matched.matched)
|
|
233
|
+
continue;
|
|
234
|
+
matchedItems.push({
|
|
235
|
+
key: matched.parsed.key,
|
|
236
|
+
scope: input.scope,
|
|
237
|
+
value: includeValues ? entry.value : undefined,
|
|
238
|
+
version: entry.version,
|
|
239
|
+
updatedAt: entry.updatedAt,
|
|
240
|
+
writer: entry.writer ?? {},
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
matchedItems.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
244
|
+
const sliced = matchedItems.slice(0, limit);
|
|
245
|
+
return {
|
|
246
|
+
runId: store.runId,
|
|
247
|
+
scope: input.scope,
|
|
248
|
+
items: sliced,
|
|
249
|
+
totalMatched: matchedItems.length,
|
|
250
|
+
};
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=shared-memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-memory.js","sourceRoot":"","sources":["../../src/core/shared-memory.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport lockfile from \"proper-lockfile\";\n\nexport type SharedMemoryScope = \"run\" | \"task\";\nexport type SharedMemoryWriteMode = \"set\" | \"append\";\n\nexport interface SharedMemoryWriter {\n\ttaskId?: string;\n\tdelegateId?: string;\n\tprofile?: string;\n}\n\nexport interface SharedMemoryContext {\n\trootCwd: string;\n\trunId: string;\n\ttaskId?: string;\n\tdelegateId?: string;\n\tprofile?: string;\n}\n\ninterface SharedMemoryEntry {\n\tvalue: string;\n\tversion: number;\n\tupdatedAt: string;\n\twriter: SharedMemoryWriter;\n}\n\ninterface SharedMemoryHistoryItem {\n\tkey: string;\n\tscope: SharedMemoryScope;\n\tmode: SharedMemoryWriteMode;\n\tversion: number;\n\tupdatedAt: string;\n\twriter: SharedMemoryWriter;\n}\n\ninterface SharedMemoryStore {\n\trunId: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tentries: Record<string, SharedMemoryEntry>;\n\thistory: SharedMemoryHistoryItem[];\n}\n\nexport interface SharedMemoryReadItem {\n\tkey: string;\n\tscope: SharedMemoryScope;\n\tvalue?: string;\n\tversion: number;\n\tupdatedAt: string;\n\twriter: SharedMemoryWriter;\n}\n\nexport interface SharedMemoryReadResult {\n\trunId: string;\n\tscope: SharedMemoryScope;\n\titems: SharedMemoryReadItem[];\n\ttotalMatched: number;\n}\n\nexport interface SharedMemoryWriteInput {\n\tkey: string;\n\tvalue: string;\n\tscope: SharedMemoryScope;\n\tmode: SharedMemoryWriteMode;\n\tifVersion?: number;\n}\n\nexport interface SharedMemoryReadInput {\n\tscope: SharedMemoryScope;\n\tkey?: string;\n\tprefix?: string;\n\tlimit?: number;\n\tincludeValues?: boolean;\n}\n\nconst maxEntryCharsDefault = 4000;\nconst maxKeysDefault = 500;\nconst historySizeDefault = 1000;\nconst lockRetryAttempts = 12;\nconst lockRetryDelayMs = 20;\n\nconst maxEntryChars = readBoundedInt(process.env.IOSM_SUBAGENT_SHARED_MEMORY_MAX_ENTRY_CHARS, maxEntryCharsDefault, 64, 20_000);\nconst maxKeys = readBoundedInt(process.env.IOSM_SUBAGENT_SHARED_MEMORY_MAX_KEYS, maxKeysDefault, 10, 20_000);\nconst historySize = readBoundedInt(process.env.IOSM_SUBAGENT_SHARED_MEMORY_HISTORY_SIZE, historySizeDefault, 10, 50_000);\n\nfunction readBoundedInt(raw: string | undefined, fallback: number, min: number, max: number): number {\n\tconst parsed = raw ? Number.parseInt(raw, 10) : fallback;\n\tif (!Number.isInteger(parsed)) return fallback;\n\treturn Math.max(min, Math.min(max, parsed));\n}\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction normalizeRunId(runId: string): string {\n\tconst trimmed = runId.trim();\n\tif (!trimmed) throw new Error(\"shared memory requires non-empty run_id context\");\n\treturn trimmed;\n}\n\nfunction normalizeKey(key: string): string {\n\tconst normalized = key.trim().replace(/\\s+/g, \" \");\n\tif (!normalized) throw new Error(\"shared memory key must be non-empty\");\n\tif (normalized.length > 240) {\n\t\tthrow new Error(\"shared memory key too long (max 240 chars)\");\n\t}\n\treturn normalized;\n}\n\nfunction resolveScopedKey(context: SharedMemoryContext, scope: SharedMemoryScope, key: string): string {\n\tconst normalizedKey = normalizeKey(key);\n\tif (scope === \"task\") {\n\t\tif (!context.taskId || !context.taskId.trim()) {\n\t\t\tthrow new Error(\"task-scoped shared memory requires task_id context\");\n\t\t}\n\t\treturn `task:${context.taskId.trim()}:${normalizedKey}`;\n\t}\n\treturn `run:${normalizedKey}`;\n}\n\nfunction parseScopedKey(scopedKey: string): { scope: SharedMemoryScope; key: string; taskId?: string } {\n\tif (scopedKey.startsWith(\"task:\")) {\n\t\tconst rest = scopedKey.slice(\"task:\".length);\n\t\tconst split = rest.indexOf(\":\");\n\t\tif (split <= 0) {\n\t\t\treturn { scope: \"task\", key: rest };\n\t\t}\n\t\treturn {\n\t\t\tscope: \"task\",\n\t\t\ttaskId: rest.slice(0, split),\n\t\t\tkey: rest.slice(split + 1),\n\t\t};\n\t}\n\tif (scopedKey.startsWith(\"run:\")) {\n\t\treturn { scope: \"run\", key: scopedKey.slice(\"run:\".length) };\n\t}\n\treturn { scope: \"run\", key: scopedKey };\n}\n\nfunction getSharedMemoryDir(rootCwd: string): string {\n\treturn join(rootCwd, \".iosm\", \"subagents\", \"shared-memory\");\n}\n\nexport function getSharedMemoryPath(rootCwd: string, runId: string): string {\n\treturn join(getSharedMemoryDir(rootCwd), `${normalizeRunId(runId)}.json`);\n}\n\nfunction createInitialStore(runId: string): SharedMemoryStore {\n\tconst now = new Date().toISOString();\n\treturn {\n\t\trunId,\n\t\tcreatedAt: now,\n\t\tupdatedAt: now,\n\t\tentries: {},\n\t\thistory: [],\n\t};\n}\n\nfunction readStore(filePath: string, runId: string): SharedMemoryStore {\n\tif (!existsSync(filePath)) {\n\t\treturn createInitialStore(runId);\n\t}\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(filePath, \"utf8\")) as SharedMemoryStore;\n\t\tif (!parsed || typeof parsed !== \"object\") return createInitialStore(runId);\n\t\tif (parsed.runId !== runId) return createInitialStore(runId);\n\t\tif (!parsed.entries || typeof parsed.entries !== \"object\") parsed.entries = {};\n\t\tif (!Array.isArray(parsed.history)) parsed.history = [];\n\t\tif (!parsed.createdAt || typeof parsed.createdAt !== \"string\") parsed.createdAt = new Date().toISOString();\n\t\tif (!parsed.updatedAt || typeof parsed.updatedAt !== \"string\") parsed.updatedAt = parsed.createdAt;\n\t\treturn parsed;\n\t} catch {\n\t\treturn createInitialStore(runId);\n\t}\n}\n\nfunction writeStore(filePath: string, store: SharedMemoryStore): void {\n\tmkdirSync(dirname(filePath), { recursive: true });\n\twriteFileSync(filePath, `${JSON.stringify(store, null, 2)}\\n`, \"utf8\");\n}\n\nasync function acquireFileLock(filePath: string): Promise<() => Promise<void>> {\n\tfor (let attempt = 1; attempt <= lockRetryAttempts; attempt += 1) {\n\t\ttry {\n\t\t\treturn await lockfile.lock(filePath, { realpath: false });\n\t\t} catch (error) {\n\t\t\tconst code = error && typeof error === \"object\" && \"code\" in error ? String(error.code) : \"\";\n\t\t\tif (code !== \"ELOCKED\" || attempt >= lockRetryAttempts) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tawait delay(lockRetryDelayMs * attempt);\n\t\t}\n\t}\n\tthrow new Error(\"failed to acquire shared memory lock\");\n}\n\nasync function withLockedStore<T>(\n\tcontext: SharedMemoryContext,\n\tfn: (store: SharedMemoryStore, filePath: string) => T,\n): Promise<T> {\n\tconst runId = normalizeRunId(context.runId);\n\tconst filePath = getSharedMemoryPath(context.rootCwd, runId);\n\tmkdirSync(dirname(filePath), { recursive: true });\n\tif (!existsSync(filePath)) {\n\t\twriteStore(filePath, createInitialStore(runId));\n\t}\n\tconst release = await acquireFileLock(filePath);\n\ttry {\n\t\tconst store = readStore(filePath, runId);\n\t\tconst value = fn(store, filePath);\n\t\twriteStore(filePath, store);\n\t\treturn value;\n\t} finally {\n\t\tawait release();\n\t}\n}\n\nfunction trimHistory(store: SharedMemoryStore): void {\n\tif (store.history.length <= historySize) return;\n\tstore.history = store.history.slice(store.history.length - historySize);\n}\n\nfunction writerFromContext(context: SharedMemoryContext): SharedMemoryWriter {\n\treturn {\n\t\ttaskId: context.taskId?.trim() || undefined,\n\t\tdelegateId: context.delegateId?.trim() || undefined,\n\t\tprofile: context.profile?.trim() || undefined,\n\t};\n}\n\nexport async function writeSharedMemory(\n\tcontext: SharedMemoryContext,\n\tinput: SharedMemoryWriteInput,\n): Promise<SharedMemoryReadItem> {\n\tconst normalizedValue = input.value;\n\tif (normalizedValue.length > maxEntryChars) {\n\t\tthrow new Error(`shared memory value exceeds ${maxEntryChars} chars`);\n\t}\n\tconst scopedKey = resolveScopedKey(context, input.scope, input.key);\n\n\treturn withLockedStore(context, (store) => {\n\t\tconst now = new Date().toISOString();\n\t\tconst entriesCount = Object.keys(store.entries).length;\n\t\tconst previous = store.entries[scopedKey];\n\t\tif (!previous && entriesCount >= maxKeys) {\n\t\t\tthrow new Error(`shared memory key limit reached (${maxKeys})`);\n\t\t}\n\t\tif (input.ifVersion !== undefined && previous && previous.version !== input.ifVersion) {\n\t\t\tthrow new Error(`shared memory CAS mismatch for key \"${input.key}\" (expected ${input.ifVersion}, got ${previous.version})`);\n\t\t}\n\t\tif (input.ifVersion !== undefined && !previous) {\n\t\t\tthrow new Error(`shared memory CAS mismatch for key \"${input.key}\" (expected ${input.ifVersion}, got 0)`);\n\t\t}\n\n\t\tconst nextValue = input.mode === \"append\" ? `${previous?.value ?? \"\"}${normalizedValue}` : normalizedValue;\n\t\tif (nextValue.length > maxEntryChars) {\n\t\t\tthrow new Error(`shared memory value exceeds ${maxEntryChars} chars after ${input.mode}`);\n\t\t}\n\t\tconst nextVersion = (previous?.version ?? 0) + 1;\n\t\tconst writer = writerFromContext(context);\n\t\tstore.entries[scopedKey] = {\n\t\t\tvalue: nextValue,\n\t\t\tversion: nextVersion,\n\t\t\tupdatedAt: now,\n\t\t\twriter,\n\t\t};\n\t\tstore.updatedAt = now;\n\t\tstore.history.push({\n\t\t\tkey: normalizeKey(input.key),\n\t\t\tscope: input.scope,\n\t\t\tmode: input.mode,\n\t\t\tversion: nextVersion,\n\t\t\tupdatedAt: now,\n\t\t\twriter,\n\t\t});\n\t\ttrimHistory(store);\n\n\t\treturn {\n\t\t\tkey: normalizeKey(input.key),\n\t\t\tscope: input.scope,\n\t\t\tvalue: nextValue,\n\t\t\tversion: nextVersion,\n\t\t\tupdatedAt: now,\n\t\t\twriter,\n\t\t};\n\t});\n}\n\nfunction matchesScopeAndPrefix(\n\tcontext: SharedMemoryContext,\n\tscopedKey: string,\n\tscope: SharedMemoryScope,\n\tkey: string | undefined,\n\tprefix: string | undefined,\n): { matched: boolean; parsed: ReturnType<typeof parseScopedKey> } {\n\tconst parsed = parseScopedKey(scopedKey);\n\tif (parsed.scope !== scope) return { matched: false, parsed };\n\tif (scope === \"task\") {\n\t\tconst taskId = context.taskId?.trim();\n\t\tif (!taskId) return { matched: false, parsed };\n\t\tif (parsed.taskId !== taskId) return { matched: false, parsed };\n\t}\n\tif (key) {\n\t\treturn { matched: parsed.key === key, parsed };\n\t}\n\tif (prefix) {\n\t\treturn { matched: parsed.key.startsWith(prefix), parsed };\n\t}\n\treturn { matched: true, parsed };\n}\n\nexport async function readSharedMemory(\n\tcontext: SharedMemoryContext,\n\tinput: SharedMemoryReadInput,\n): Promise<SharedMemoryReadResult> {\n\tconst normalizedKey = input.key ? normalizeKey(input.key) : undefined;\n\tconst normalizedPrefix = input.prefix ? normalizeKey(input.prefix) : undefined;\n\tconst limit = Math.max(1, Math.min(100, input.limit ?? 20));\n\tconst includeValues = input.includeValues !== false;\n\n\treturn withLockedStore(context, (store) => {\n\t\tconst matchedItems: SharedMemoryReadItem[] = [];\n\t\tfor (const [scopedKey, entry] of Object.entries(store.entries)) {\n\t\t\tconst matched = matchesScopeAndPrefix(context, scopedKey, input.scope, normalizedKey, normalizedPrefix);\n\t\t\tif (!matched.matched) continue;\n\t\t\tmatchedItems.push({\n\t\t\t\tkey: matched.parsed.key,\n\t\t\t\tscope: input.scope,\n\t\t\t\tvalue: includeValues ? entry.value : undefined,\n\t\t\t\tversion: entry.version,\n\t\t\t\tupdatedAt: entry.updatedAt,\n\t\t\t\twriter: entry.writer ?? {},\n\t\t\t});\n\t\t}\n\n\t\tmatchedItems.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));\n\t\tconst sliced = matchedItems.slice(0, limit);\n\t\treturn {\n\t\t\trunId: store.runId,\n\t\t\tscope: input.scope,\n\t\t\titems: sliced,\n\t\t\ttotalMatched: matchedItems.length,\n\t\t};\n\t});\n}\n"]}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { EngineeringContract } from "./contract.js";
|
|
2
|
+
export type SingularComplexity = "low" | "medium" | "high";
|
|
3
|
+
export type SingularBlastRadius = "low" | "medium" | "high";
|
|
4
|
+
export type SingularRecommendation = "implement_now" | "implement_incrementally" | "defer";
|
|
5
|
+
export type SingularStageFit = "needed_now" | "optional_now" | "later";
|
|
6
|
+
export interface SingularImpactAnalysis {
|
|
7
|
+
codebase: string;
|
|
8
|
+
delivery: string;
|
|
9
|
+
risks: string;
|
|
10
|
+
operations: string;
|
|
11
|
+
}
|
|
12
|
+
export interface SingularOption {
|
|
13
|
+
id: string;
|
|
14
|
+
title: string;
|
|
15
|
+
summary: string;
|
|
16
|
+
complexity: SingularComplexity;
|
|
17
|
+
blast_radius: SingularBlastRadius;
|
|
18
|
+
suggested_files: string[];
|
|
19
|
+
plan: string[];
|
|
20
|
+
pros: string[];
|
|
21
|
+
cons: string[];
|
|
22
|
+
when_to_choose?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface SingularAnalysisResult {
|
|
25
|
+
runId: string;
|
|
26
|
+
request: string;
|
|
27
|
+
generatedAt: string;
|
|
28
|
+
scannedFiles: number;
|
|
29
|
+
sourceFiles: number;
|
|
30
|
+
testFiles: number;
|
|
31
|
+
matchedFiles: string[];
|
|
32
|
+
baselineComplexity: SingularComplexity;
|
|
33
|
+
baselineBlastRadius: SingularBlastRadius;
|
|
34
|
+
recommendation: SingularRecommendation;
|
|
35
|
+
recommendationReason: string;
|
|
36
|
+
stageFit?: SingularStageFit;
|
|
37
|
+
stageFitReason?: string;
|
|
38
|
+
impactAnalysis?: SingularImpactAnalysis;
|
|
39
|
+
contractSignals: string[];
|
|
40
|
+
options: SingularOption[];
|
|
41
|
+
}
|
|
42
|
+
export interface SingularLastRun {
|
|
43
|
+
runId: string;
|
|
44
|
+
analysisPath: string;
|
|
45
|
+
metaPath?: string;
|
|
46
|
+
request?: string;
|
|
47
|
+
recommendation?: SingularRecommendation;
|
|
48
|
+
generatedAt?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface SingularAnalyzeOptions {
|
|
51
|
+
request: string;
|
|
52
|
+
contract?: EngineeringContract;
|
|
53
|
+
autosave?: boolean;
|
|
54
|
+
}
|
|
55
|
+
export interface SingularServiceOptions {
|
|
56
|
+
cwd: string;
|
|
57
|
+
}
|
|
58
|
+
export declare class SingularService {
|
|
59
|
+
private readonly cwd;
|
|
60
|
+
constructor(options: SingularServiceOptions);
|
|
61
|
+
getAnalysesRoot(): string;
|
|
62
|
+
getLastRun(): SingularLastRun | undefined;
|
|
63
|
+
analyze(options: SingularAnalyzeOptions): Promise<SingularAnalysisResult>;
|
|
64
|
+
saveAnalysis(result: SingularAnalysisResult): void;
|
|
65
|
+
private saveRunArtifacts;
|
|
66
|
+
private scanRepository;
|
|
67
|
+
private walkFiles;
|
|
68
|
+
private collectContractSignals;
|
|
69
|
+
private estimateComplexityScore;
|
|
70
|
+
private buildRecommendation;
|
|
71
|
+
private buildOptions;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=singular.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"singular.d.ts","sourceRoot":"","sources":["../../src/core/singular.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAC3D,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAC5D,MAAM,MAAM,sBAAsB,GAAG,eAAe,GAAG,yBAAyB,GAAG,OAAO,CAAC;AAC3F,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,cAAc,GAAG,OAAO,CAAC;AAEvE,MAAM,WAAW,sBAAsB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,YAAY,EAAE,mBAAmB,CAAC;IAClC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,cAAc,EAAE,sBAAsB,CAAC;IACvC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,sBAAsB,CAAC;IACxC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,EAAE,cAAc,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,sBAAsB,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACtC,GAAG,EAAE,MAAM,CAAC;CACZ;AAoGD,qBAAa,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;gBAEjB,OAAO,EAAE,sBAAsB;IAI3C,eAAe,IAAI,MAAM;IAIzB,UAAU,IAAI,eAAe,GAAG,SAAS;IA4CnC,OAAO,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAoD/E,YAAY,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI;IAIlD,OAAO,CAAC,gBAAgB;IA2BxB,OAAO,CAAC,cAAc;IA+CtB,OAAO,CAAC,SAAS;IAsCjB,OAAO,CAAC,sBAAsB;IAa9B,OAAO,CAAC,uBAAuB;IA8B/B,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,YAAY;CAmEpB"}
|