@rubytech/taskmaster 1.12.2 → 1.13.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/dist/agents/auth-profiles/consolidate.js +72 -0
- package/dist/agents/auth-profiles/oauth.js +0 -24
- package/dist/agents/auth-profiles/paths.js +4 -4
- package/dist/agents/auth-profiles/store.js +8 -100
- package/dist/agents/model-fallback.js +26 -1
- package/dist/agents/pi-embedded-runner/run/payloads.js +8 -0
- package/dist/agents/session-transcript-repair.js +3 -2
- package/dist/agents/system-prompt.js +1 -0
- package/dist/agents/taskmaster-tools.js +2 -0
- package/dist/agents/tool-policy.js +2 -0
- package/dist/agents/tools/opening-hours-tool.js +92 -0
- package/dist/agents/tools/web-fetch.js +8 -3
- package/dist/agents/tools/web-search.js +7 -4
- package/dist/agents/workspace-migrations.js +47 -0
- package/dist/build-info.json +3 -3
- package/dist/commands/agents.commands.add.js +1 -32
- package/dist/config/defaults.js +1 -1
- package/dist/config/legacy.migrations.part-3.js +25 -4
- package/dist/config/sessions/transcript.js +31 -0
- package/dist/config/types.business.js +1 -0
- package/dist/config/zod-schema.js +33 -0
- package/dist/control-ui/assets/{index-CpaEIgQy.css → index-B8I8lMfz.css} +1 -1
- package/dist/control-ui/assets/{index-CP9IoaZp.js → index-BWqMMgRV.js} +537 -425
- package/dist/control-ui/assets/index-BWqMMgRV.js.map +1 -0
- package/dist/control-ui/index.html +2 -2
- package/dist/gateway/config-reload.js +1 -0
- package/dist/gateway/server-close.js +8 -0
- package/dist/gateway/server-methods/business.js +31 -0
- package/dist/gateway/server-methods/network.js +19 -6
- package/dist/gateway/server-methods/tailscale.js +2 -2
- package/dist/gateway/server-methods.js +5 -1
- package/dist/gateway/server.impl.js +42 -0
- package/dist/infra/heartbeat-infra-alert.js +54 -0
- package/dist/memory/manager.js +5 -5
- package/dist/web/auto-reply/monitor/process-message.js +24 -0
- package/dist/web/inbound/access-control.js +2 -1
- package/dist/web/inbound/monitor.js +32 -10
- package/dist/web/inbound/owner-mirror.js +35 -0
- package/package.json +1 -1
- package/skills/anthropic/SKILL.md +30 -0
- package/skills/anthropic/references/setup-guide.md +146 -0
- package/skills/google-ai/SKILL.md +3 -2
- package/skills/google-ai/references/setup-guide.md +94 -0
- package/skills/log-review/SKILL.md +45 -0
- package/skills/log-review/cron-template.json +21 -0
- package/skills/log-review/references/review-protocol.md +65 -0
- package/skills/openai/SKILL.md +28 -0
- package/skills/openai/references/setup-guide.md +122 -0
- package/taskmaster-docs/USER-GUIDE.md +31 -2
- package/templates/beagle-taxi/memory/public/investors-knowledge-base.md +230 -0
- package/templates/beagle-taxi/skills/beagle-taxi/SKILL.md +3 -1
- package/templates/customer/agents/admin/BOOTSTRAP.md +14 -2
- package/templates/customer/agents/public/AGENTS.md +15 -0
- package/templates/education-hero/agents/admin/BOOTSTRAP.md +14 -2
- package/templates/real-agent/agents/admin/AGENTS.md +139 -0
- package/templates/real-agent/agents/admin/HEARTBEAT.md +12 -0
- package/templates/real-agent/agents/admin/IDENTITY.md +11 -0
- package/templates/real-agent/agents/admin/SOUL.md +38 -0
- package/templates/real-agent/agents/public/AGENTS.md +183 -0
- package/templates/real-agent/agents/public/IDENTITY.md +8 -0
- package/templates/real-agent/agents/public/SOUL.md +75 -0
- package/templates/real-agent/memory/admin/.gitkeep +0 -0
- package/templates/real-agent/memory/public/contributors/adam-mackay.md +7 -0
- package/templates/real-agent/memory/public/contributors/alex-pelosi-buchanan.md +7 -0
- package/templates/real-agent/memory/public/contributors/jamie-fisher.md +7 -0
- package/templates/real-agent/memory/public/contributors/john-savage.md +7 -0
- package/templates/real-agent/memory/public/contributors/melanie-attwater.md +7 -0
- package/templates/real-agent/memory/public/contributors/regina-mangan.md +7 -0
- package/templates/real-agent/memory/public/contributors/richard-rawlings.md +7 -0
- package/templates/real-agent/memory/public/contributors/roger-black.md +7 -0
- package/templates/real-agent/memory/public/contributors/steve-backley.md +7 -0
- package/templates/real-agent/memory/public/courses/agency-blueprint/.gitkeep +0 -0
- package/templates/real-agent/memory/public/courses/podcast/.gitkeep +0 -0
- package/templates/real-agent/memory/public/courses/real-business/.gitkeep +0 -0
- package/templates/real-agent/memory/public/courses/real-coaching/.gitkeep +0 -0
- package/templates/real-agent/memory/public/courses/real-marketing/.gitkeep +0 -0
- package/templates/real-agent/memory/public/resources/.gitkeep +0 -0
- package/templates/real-agent/memory/shared/.gitkeep +0 -0
- package/templates/real-agent/memory/users/.gitkeep +0 -0
- package/templates/real-agent/skills/bespoke-coaching/SKILL.md +29 -0
- package/templates/real-agent/skills/bespoke-coaching/references/coaching-boundaries.md +56 -0
- package/templates/real-agent/skills/bespoke-coaching/references/feedback-framework.md +61 -0
- package/templates/real-agent/skills/bootstrap/SKILL.md +27 -0
- package/templates/real-agent/skills/bootstrap/references/onboarding-flow.md +63 -0
- package/templates/real-agent/skills/content-directory/SKILL.md +40 -0
- package/templates/real-agent/skills/content-directory/references/module-delivery.md +65 -0
- package/templates/real-agent/skills/content-directory/references/progress-tracking.md +47 -0
- package/templates/tradesupport/agents/admin/BOOTSTRAP.md +14 -2
- package/dist/control-ui/assets/index-CP9IoaZp.js.map +0 -1
|
@@ -116,9 +116,56 @@ async function patchOwnerLearning(agentsPath, content) {
|
|
|
116
116
|
return null;
|
|
117
117
|
return insertSection(content, OWNER_LEARNING_SECTION, findCapabilitiesInsertPoint);
|
|
118
118
|
}
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
// Migration: Public Agent Security (cross-user isolation)
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
const PUBLIC_SECURITY_SECTION = `## Security
|
|
123
|
+
|
|
124
|
+
**User isolation is absolute.** Each user conversation is a sealed scope. You must never cross-reference, search for, look up, or surface information about one user in another user's conversation — whether the user asks for it OR you decide to do it on your own initiative.
|
|
125
|
+
|
|
126
|
+
**Never:**
|
|
127
|
+
- Search memory for another user's personal details (name, phone, address, history)
|
|
128
|
+
- Attempt to identify, verify, or correlate users across conversations
|
|
129
|
+
- Relay, summarise, or reference information from one user's session in another
|
|
130
|
+
- Proactively look up contact details for people mentioned in system messages
|
|
131
|
+
|
|
132
|
+
If a user asks for information about another person, politely decline — it would violate strict security protocols.`;
|
|
133
|
+
function hasSecurityIsolationSection(content) {
|
|
134
|
+
return content.includes("User isolation is absolute");
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Find insertion point after the "## Every Session" block's trailing `---`.
|
|
138
|
+
* Falls back to inserting before the first `## ` heading after the title.
|
|
139
|
+
*/
|
|
140
|
+
function findPostEverySessionInsertPoint(content) {
|
|
141
|
+
const everySessionIdx = content.indexOf("## Every Session");
|
|
142
|
+
if (everySessionIdx !== -1) {
|
|
143
|
+
const separatorIdx = content.indexOf("---", everySessionIdx);
|
|
144
|
+
if (separatorIdx !== -1) {
|
|
145
|
+
const afterSeparator = separatorIdx + 3;
|
|
146
|
+
// Skip any whitespace after the separator
|
|
147
|
+
const rest = content.slice(afterSeparator);
|
|
148
|
+
const trimmedStart = rest.length - rest.trimStart().length;
|
|
149
|
+
return afterSeparator + trimmedStart;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Fallback: insert before the first ## heading after the title line
|
|
153
|
+
const firstHeading = content.indexOf("\n## ", content.indexOf("\n") + 1);
|
|
154
|
+
if (firstHeading !== -1)
|
|
155
|
+
return firstHeading + 1; // after the newline
|
|
156
|
+
return -1;
|
|
157
|
+
}
|
|
158
|
+
async function patchPublicSecurity(agentsPath, content) {
|
|
159
|
+
if (!isPublicAgent(content))
|
|
160
|
+
return null;
|
|
161
|
+
if (hasSecurityIsolationSection(content))
|
|
162
|
+
return null;
|
|
163
|
+
return insertSection(content, PUBLIC_SECURITY_SECTION, findPostEverySessionInsertPoint);
|
|
164
|
+
}
|
|
119
165
|
const MIGRATIONS = [
|
|
120
166
|
{ name: "skill-recommendations", apply: patchSkillRecommendations },
|
|
121
167
|
{ name: "owner-learning", apply: patchOwnerLearning },
|
|
168
|
+
{ name: "public-security", apply: patchPublicSecurity },
|
|
122
169
|
];
|
|
123
170
|
/**
|
|
124
171
|
* Run all workspace migrations for every configured agent.
|
package/dist/build-info.json
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { resolveAgentDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, } from "../agents/agent-scope.js";
|
|
1
|
+
import { resolveAgentDir, resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
|
|
4
2
|
import { ensureAuthProfileStore } from "../agents/auth-profiles.js";
|
|
5
|
-
import { resolveAuthStorePath } from "../agents/auth-profiles/paths.js";
|
|
6
3
|
import { writeConfigFile } from "../config/config.js";
|
|
7
4
|
import { logConfigUpdated } from "../config/logging.js";
|
|
8
5
|
import { DEFAULT_AGENT_ID, normalizeAgentId } from "../routing/session-key.js";
|
|
@@ -17,15 +14,6 @@ import { applyAuthChoice, warnIfModelConfigLooksOff } from "./auth-choice.js";
|
|
|
17
14
|
import { promptAuthChoiceGrouped } from "./auth-choice-prompt.js";
|
|
18
15
|
import { setupChannels } from "./onboard-channels.js";
|
|
19
16
|
import { ensureWorkspaceAndSessions } from "./onboard-helpers.js";
|
|
20
|
-
async function fileExists(pathname) {
|
|
21
|
-
try {
|
|
22
|
-
await fs.stat(pathname);
|
|
23
|
-
return true;
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
17
|
export async function agentsAddCommand(opts, runtime = defaultRuntime, params) {
|
|
30
18
|
const cfg = await requireValidConfig(runtime);
|
|
31
19
|
if (!cfg)
|
|
@@ -173,25 +161,6 @@ export async function agentsAddCommand(opts, runtime = defaultRuntime, params) {
|
|
|
173
161
|
workspace: workspaceDir,
|
|
174
162
|
agentDir,
|
|
175
163
|
});
|
|
176
|
-
const defaultAgentId = resolveDefaultAgentId(cfg);
|
|
177
|
-
if (defaultAgentId !== agentId) {
|
|
178
|
-
const sourceAuthPath = resolveAuthStorePath(resolveAgentDir(cfg, defaultAgentId));
|
|
179
|
-
const destAuthPath = resolveAuthStorePath(agentDir);
|
|
180
|
-
const sameAuthPath = path.resolve(sourceAuthPath).toLowerCase() === path.resolve(destAuthPath).toLowerCase();
|
|
181
|
-
if (!sameAuthPath &&
|
|
182
|
-
(await fileExists(sourceAuthPath)) &&
|
|
183
|
-
!(await fileExists(destAuthPath))) {
|
|
184
|
-
const shouldCopy = await prompter.confirm({
|
|
185
|
-
message: `Copy auth profiles from "${defaultAgentId}"?`,
|
|
186
|
-
initialValue: false,
|
|
187
|
-
});
|
|
188
|
-
if (shouldCopy) {
|
|
189
|
-
await fs.mkdir(path.dirname(destAuthPath), { recursive: true });
|
|
190
|
-
await fs.copyFile(sourceAuthPath, destAuthPath);
|
|
191
|
-
await prompter.note(`Copied auth profiles from "${defaultAgentId}".`, "Auth profiles");
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
164
|
const wantsAuth = await prompter.confirm({
|
|
196
165
|
message: "Configure model/auth for this agent now?",
|
|
197
166
|
initialValue: false,
|
package/dist/config/defaults.js
CHANGED
|
@@ -331,8 +331,8 @@ export function applyContextPruningDefaults(cfg) {
|
|
|
331
331
|
* silently skipped at runtime, so listing them here is always safe.
|
|
332
332
|
*/
|
|
333
333
|
const DEFAULT_MODEL_FALLBACKS = [
|
|
334
|
-
"google/gemini-3-pro-preview",
|
|
335
334
|
"openai/gpt-5.2",
|
|
335
|
+
"google/gemini-3-pro-preview",
|
|
336
336
|
];
|
|
337
337
|
export function applyModelFallbackDefaults(cfg) {
|
|
338
338
|
const model = cfg.agents?.defaults?.model;
|
|
@@ -246,7 +246,7 @@ export const LEGACY_CONFIG_MIGRATIONS_PART_3 = [
|
|
|
246
246
|
},
|
|
247
247
|
{
|
|
248
248
|
id: "agents.defaults.model.fallbacks-defaults",
|
|
249
|
-
describe: "Set default model fallback chain (
|
|
249
|
+
describe: "Set default model fallback chain (OpenAI GPT-5.2, Google Gemini Pro)",
|
|
250
250
|
apply: (raw, changes) => {
|
|
251
251
|
const agents = getRecord(raw.agents);
|
|
252
252
|
const defaults = getRecord(agents?.defaults);
|
|
@@ -257,14 +257,35 @@ export const LEGACY_CONFIG_MIGRATIONS_PART_3 = [
|
|
|
257
257
|
// Already has non-empty fallbacks — respect the user's choice.
|
|
258
258
|
if (Array.isArray(model.fallbacks) && model.fallbacks.length > 0)
|
|
259
259
|
return;
|
|
260
|
-
model.fallbacks = ["google/gemini-3-pro-preview"
|
|
260
|
+
model.fallbacks = ["openai/gpt-5.2", "google/gemini-3-pro-preview"];
|
|
261
261
|
}
|
|
262
262
|
else {
|
|
263
263
|
defaults.model = {
|
|
264
|
-
fallbacks: ["google/gemini-3-pro-preview"
|
|
264
|
+
fallbacks: ["openai/gpt-5.2", "google/gemini-3-pro-preview"],
|
|
265
265
|
};
|
|
266
266
|
}
|
|
267
|
-
changes.push("Set default model fallbacks: google/gemini-3-pro-preview
|
|
267
|
+
changes.push("Set default model fallbacks: openai/gpt-5.2, google/gemini-3-pro-preview.");
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
id: "agents.defaults.model.fallbacks-reorder-openai-first",
|
|
272
|
+
describe: "Reorder default model fallbacks: OpenAI before Google",
|
|
273
|
+
apply: (raw, changes) => {
|
|
274
|
+
const agents = getRecord(raw.agents);
|
|
275
|
+
const defaults = getRecord(agents?.defaults);
|
|
276
|
+
if (!defaults)
|
|
277
|
+
return;
|
|
278
|
+
const model = getRecord(defaults.model);
|
|
279
|
+
if (!model || !Array.isArray(model.fallbacks))
|
|
280
|
+
return;
|
|
281
|
+
const fb = model.fallbacks;
|
|
282
|
+
// Only swap if it matches the old default order exactly.
|
|
283
|
+
if (fb.length === 2 &&
|
|
284
|
+
fb[0] === "google/gemini-3-pro-preview" &&
|
|
285
|
+
fb[1] === "openai/gpt-5.2") {
|
|
286
|
+
model.fallbacks = ["openai/gpt-5.2", "google/gemini-3-pro-preview"];
|
|
287
|
+
changes.push("Reordered model fallbacks: openai/gpt-5.2 before google/gemini-3-pro-preview.");
|
|
288
|
+
}
|
|
268
289
|
},
|
|
269
290
|
},
|
|
270
291
|
{
|
|
@@ -111,3 +111,34 @@ export async function appendAssistantMessageToSessionTranscript(params) {
|
|
|
111
111
|
emitSessionTranscriptUpdate(sessionFile);
|
|
112
112
|
return { ok: true, sessionFile };
|
|
113
113
|
}
|
|
114
|
+
export async function appendUserMessageToSessionTranscript(params) {
|
|
115
|
+
const sessionKey = params.sessionKey.trim();
|
|
116
|
+
if (!sessionKey)
|
|
117
|
+
return { ok: false, reason: "missing sessionKey" };
|
|
118
|
+
const text = params.text.trim();
|
|
119
|
+
if (!text)
|
|
120
|
+
return { ok: false, reason: "empty text" };
|
|
121
|
+
const storePath = params.storePath ?? resolveDefaultSessionStorePath(params.agentId);
|
|
122
|
+
const store = loadSessionStore(storePath, { skipCache: true });
|
|
123
|
+
const entry = store[sessionKey];
|
|
124
|
+
if (!entry?.sessionId)
|
|
125
|
+
return { ok: false, reason: `unknown sessionKey: ${sessionKey}` };
|
|
126
|
+
const sessionFile = entry.sessionFile?.trim() || resolveSessionTranscriptPath(entry.sessionId, params.agentId);
|
|
127
|
+
await ensureSessionHeader({ sessionFile, sessionId: entry.sessionId });
|
|
128
|
+
const sessionManager = SessionManager.open(sessionFile);
|
|
129
|
+
sessionManager.appendMessage({
|
|
130
|
+
role: "user",
|
|
131
|
+
content: [{ type: "text", text }],
|
|
132
|
+
timestamp: Date.now(),
|
|
133
|
+
});
|
|
134
|
+
if (!entry.sessionFile || entry.sessionFile !== sessionFile) {
|
|
135
|
+
await updateSessionStore(storePath, (current) => {
|
|
136
|
+
current[sessionKey] = {
|
|
137
|
+
...entry,
|
|
138
|
+
sessionFile,
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
emitSessionTranscriptUpdate(sessionFile);
|
|
143
|
+
return { ok: true, sessionFile };
|
|
144
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -24,6 +24,14 @@ const NodeHostSchema = z
|
|
|
24
24
|
})
|
|
25
25
|
.strict()
|
|
26
26
|
.optional();
|
|
27
|
+
const DayScheduleSchema = z
|
|
28
|
+
.object({
|
|
29
|
+
start: z.string().regex(/^\d{2}:\d{2}$/),
|
|
30
|
+
end: z.string().regex(/^\d{2}:\d{2}$/),
|
|
31
|
+
})
|
|
32
|
+
.strict()
|
|
33
|
+
.nullable()
|
|
34
|
+
.optional();
|
|
27
35
|
export const TaskmasterSchema = z
|
|
28
36
|
.object({
|
|
29
37
|
meta: z
|
|
@@ -233,6 +241,31 @@ export const TaskmasterSchema = z
|
|
|
233
241
|
})
|
|
234
242
|
.strict()
|
|
235
243
|
.optional(),
|
|
244
|
+
business: z
|
|
245
|
+
.object({
|
|
246
|
+
openingHours: z
|
|
247
|
+
.object({
|
|
248
|
+
enabled: z.boolean(),
|
|
249
|
+
timezone: z.string().min(1).optional(),
|
|
250
|
+
schedule: z
|
|
251
|
+
.object({
|
|
252
|
+
monday: DayScheduleSchema,
|
|
253
|
+
tuesday: DayScheduleSchema,
|
|
254
|
+
wednesday: DayScheduleSchema,
|
|
255
|
+
thursday: DayScheduleSchema,
|
|
256
|
+
friday: DayScheduleSchema,
|
|
257
|
+
saturday: DayScheduleSchema,
|
|
258
|
+
sunday: DayScheduleSchema,
|
|
259
|
+
})
|
|
260
|
+
.strict(),
|
|
261
|
+
closedDates: z.array(z.string().regex(/^\d{4}-\d{2}-\d{2}$/)).optional(),
|
|
262
|
+
})
|
|
263
|
+
.strict()
|
|
264
|
+
.optional(),
|
|
265
|
+
publicAgentEnabled: z.boolean().optional(),
|
|
266
|
+
})
|
|
267
|
+
.strict()
|
|
268
|
+
.optional(),
|
|
236
269
|
hooks: z
|
|
237
270
|
.object({
|
|
238
271
|
enabled: z.boolean().optional(),
|