@docyrus/docyrus 0.0.34 → 0.0.35
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 +25 -0
- package/agent-loader.js +3 -2
- package/agent-loader.js.map +2 -2
- package/main.js +82162 -46093
- package/main.js.map +4 -4
- package/package.json +12 -3
- package/resources/chrome-tools/browser-content.js +46 -46
- package/resources/chrome-tools/browser-cookies.js +16 -16
- package/resources/chrome-tools/browser-eval.js +27 -27
- package/resources/chrome-tools/browser-hn-scraper.js +1 -1
- package/resources/chrome-tools/browser-nav.js +23 -23
- package/resources/chrome-tools/browser-pick.js +127 -127
- package/resources/chrome-tools/browser-screenshot.js +10 -10
- package/resources/chrome-tools/browser-start.js +38 -38
- package/resources/pi-agent/extensions/answer.ts +392 -384
- package/resources/pi-agent/extensions/context.ts +415 -415
- package/resources/pi-agent/extensions/control.ts +1287 -1287
- package/resources/pi-agent/extensions/diff.ts +171 -171
- package/resources/pi-agent/extensions/files.ts +155 -155
- package/resources/pi-agent/extensions/knowledge.ts +664 -0
- package/resources/pi-agent/extensions/loop.ts +375 -375
- package/resources/pi-agent/extensions/pi-bash-live-view/index.ts +1 -1
- package/resources/pi-agent/extensions/pi-bash-live-view/package.json +22 -22
- package/resources/pi-agent/extensions/pi-bash-live-view/pty-execute.ts +2 -2
- package/resources/pi-agent/extensions/pi-bash-live-view/pty-session.ts +2 -2
- package/resources/pi-agent/extensions/pi-bash-live-view/spawn-helper.ts +2 -2
- package/resources/pi-agent/extensions/pi-bash-live-view/terminal-emulator.ts +18 -18
- package/resources/pi-agent/extensions/pi-bash-live-view/truncate.ts +1 -1
- package/resources/pi-agent/extensions/pi-bash-live-view/widget.ts +4 -4
- package/resources/pi-agent/extensions/pi-custom-compaction/package.json +4 -4
- package/resources/pi-agent/extensions/pi-mcp-adapter/app-bridge.bundle.js +14 -14
- package/resources/pi-agent/extensions/pi-mcp-adapter/commands.ts +6 -6
- package/resources/pi-agent/extensions/pi-mcp-adapter/config.ts +9 -9
- package/resources/pi-agent/extensions/pi-mcp-adapter/consent-manager.ts +4 -4
- package/resources/pi-agent/extensions/pi-mcp-adapter/direct-tools.ts +13 -13
- package/resources/pi-agent/extensions/pi-mcp-adapter/glimpse-ui.ts +5 -5
- package/resources/pi-agent/extensions/pi-mcp-adapter/host-html-template.ts +13 -13
- package/resources/pi-agent/extensions/pi-mcp-adapter/index.ts +14 -14
- package/resources/pi-agent/extensions/pi-mcp-adapter/init.ts +17 -17
- package/resources/pi-agent/extensions/pi-mcp-adapter/lifecycle.ts +2 -2
- package/resources/pi-agent/extensions/pi-mcp-adapter/logger.ts +2 -2
- package/resources/pi-agent/extensions/pi-mcp-adapter/mcp-panel.ts +17 -17
- package/resources/pi-agent/extensions/pi-mcp-adapter/metadata-cache.ts +9 -9
- package/resources/pi-agent/extensions/pi-mcp-adapter/npx-resolver.ts +35 -35
- package/resources/pi-agent/extensions/pi-mcp-adapter/oauth-handler.ts +1 -1
- package/resources/pi-agent/extensions/pi-mcp-adapter/proxy-modes.ts +12 -12
- package/resources/pi-agent/extensions/pi-mcp-adapter/server-manager.ts +6 -6
- package/resources/pi-agent/extensions/pi-mcp-adapter/tool-metadata.ts +4 -4
- package/resources/pi-agent/extensions/pi-mcp-adapter/types.ts +2 -2
- package/resources/pi-agent/extensions/pi-mcp-adapter/ui-resource-handler.ts +6 -6
- package/resources/pi-agent/extensions/pi-mcp-adapter/ui-server.ts +17 -17
- package/resources/pi-agent/extensions/pi-mcp-adapter/ui-session.ts +22 -22
- package/resources/pi-agent/extensions/pi-mcp-adapter/utils.ts +2 -2
- package/resources/pi-agent/extensions/prompt-editor.ts +900 -900
- package/resources/pi-agent/extensions/prompt-url-widget.ts +122 -122
- package/resources/pi-agent/extensions/redraws.ts +14 -14
- package/resources/pi-agent/extensions/review.ts +1533 -1533
- package/resources/pi-agent/extensions/todos.ts +1735 -1735
- package/resources/pi-agent/extensions/tps.ts +40 -40
- package/resources/pi-agent/extensions/whimsical.ts +3 -3
- package/resources/pi-agent/prompts/agent-system.md +2 -0
- package/resources/pi-agent/prompts/coder-system.md +2 -0
- package/server-loader.js +82 -1
- package/server-loader.js.map +3 -3
- package/tui.mjs +2 -0
- package/tui.mjs.map +1 -1
|
@@ -2,46 +2,46 @@ import type { AssistantMessage } from "@mariozechner/pi-ai";
|
|
|
2
2
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
3
3
|
|
|
4
4
|
function isAssistantMessage(message: unknown): message is AssistantMessage {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
if (!message || typeof message !== "object") {return false;}
|
|
6
|
+
const role = (message as { role?: unknown }).role;
|
|
7
|
+
return role === "assistant";
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export default function
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
10
|
+
export default function(pi: ExtensionAPI) {
|
|
11
|
+
let agentStartMs: number | null = null;
|
|
12
|
+
|
|
13
|
+
pi.on("agent_start", () => {
|
|
14
|
+
agentStartMs = Date.now();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
pi.on("agent_end", (event, ctx) => {
|
|
18
|
+
if (!ctx.hasUI) {return;}
|
|
19
|
+
if (agentStartMs === null) {return;}
|
|
20
|
+
|
|
21
|
+
const elapsedMs = Date.now() - agentStartMs;
|
|
22
|
+
agentStartMs = null;
|
|
23
|
+
if (elapsedMs <= 0) {return;}
|
|
24
|
+
|
|
25
|
+
let input = 0;
|
|
26
|
+
let output = 0;
|
|
27
|
+
let cacheRead = 0;
|
|
28
|
+
let cacheWrite = 0;
|
|
29
|
+
let totalTokens = 0;
|
|
30
|
+
|
|
31
|
+
for (const message of event.messages) {
|
|
32
|
+
if (!isAssistantMessage(message)) {continue;}
|
|
33
|
+
input += message.usage.input || 0;
|
|
34
|
+
output += message.usage.output || 0;
|
|
35
|
+
cacheRead += message.usage.cacheRead || 0;
|
|
36
|
+
cacheWrite += message.usage.cacheWrite || 0;
|
|
37
|
+
totalTokens += message.usage.totalTokens || 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (output <= 0) {return;}
|
|
41
|
+
|
|
42
|
+
const elapsedSeconds = elapsedMs / 1000;
|
|
43
|
+
const tokensPerSecond = output / elapsedSeconds;
|
|
44
|
+
const message = `TPS ${tokensPerSecond.toFixed(1)} tok/s. out ${output.toLocaleString()}, in ${input.toLocaleString()}, cache r/w ${cacheRead.toLocaleString()}/${cacheWrite.toLocaleString()}, total ${totalTokens.toLocaleString()}, ${elapsedSeconds.toFixed(1)}s`;
|
|
45
|
+
ctx.ui.notify(message, "info");
|
|
46
|
+
});
|
|
47
47
|
}
|
|
@@ -463,12 +463,12 @@ function pickRandom(): string {
|
|
|
463
463
|
return messages[Math.floor(Math.random() * messages.length)];
|
|
464
464
|
}
|
|
465
465
|
|
|
466
|
-
export default function
|
|
467
|
-
pi.on("turn_start", async
|
|
466
|
+
export default function(pi: ExtensionAPI) {
|
|
467
|
+
pi.on("turn_start", async(_event, ctx) => {
|
|
468
468
|
ctx.ui.setWorkingMessage(pickRandom());
|
|
469
469
|
});
|
|
470
470
|
|
|
471
|
-
pi.on("turn_end", async
|
|
471
|
+
pi.on("turn_end", async(_event, ctx) => {
|
|
472
472
|
ctx.ui.setWorkingMessage(); // Reset for next time
|
|
473
473
|
});
|
|
474
474
|
}
|
|
@@ -7,6 +7,8 @@ Core behavior:
|
|
|
7
7
|
- Prefer the local `docyrus` CLI for Docyrus operations instead of guessing undocumented HTTP endpoints.
|
|
8
8
|
- When you need structured command output, prefer `--json`.
|
|
9
9
|
- Start by inspecting real tenant state before making claims about apps, data sources, users, environments, auth state, or API shape.
|
|
10
|
+
- If the repository contains `docyrus/knowledge/`, use `docyrus knowledge search`, `docyrus knowledge section`, and `docyrus knowledge expand` before broader repo exploration.
|
|
11
|
+
- When `docyrus/knowledge/` exists, keep it updated and finish local work with `docyrus knowledge check`.
|
|
10
12
|
- Use the installed Docyrus skills as your command and workflow reference.
|
|
11
13
|
- Be careful with tenant-scoped mutations. Confirm real identifiers and current context before changing state.
|
|
12
14
|
- Treat auth files, tokens, and `.docyrus` contents as sensitive.
|
|
@@ -18,6 +18,8 @@ Core behavior:
|
|
|
18
18
|
|
|
19
19
|
- Use repository files and coding tools for implementation work.
|
|
20
20
|
- Use the local `docyrus` CLI for Docyrus platform state, tenant context, schema inspection, app and data-source operations, API discovery, and data verification.
|
|
21
|
+
- If the repository contains `docyrus/knowledge/`, use `docyrus knowledge search`, `docyrus knowledge section`, and `docyrus knowledge expand` before coding so you start from documented repo intent rather than only source inspection.
|
|
22
|
+
- When `docyrus/knowledge/` exists, keep it in sync with behavior changes and finish with `docyrus knowledge check`.
|
|
21
23
|
- Prefer `--json` whenever command output needs to be parsed, compared, or fed back into reasoning.
|
|
22
24
|
- Start from real state before making claims about apps, data sources, users, fields, enums, environments, auth state, API shape, or deployment context.
|
|
23
25
|
- Distinguish clearly between local code changes and remote Docyrus platform mutations.
|
package/server-loader.js
CHANGED
|
@@ -723,6 +723,7 @@ var AgentEnvStore = class {
|
|
|
723
723
|
constructor(filePath) {
|
|
724
724
|
this.filePath = filePath;
|
|
725
725
|
}
|
|
726
|
+
filePath;
|
|
726
727
|
getFilePath() {
|
|
727
728
|
return this.filePath;
|
|
728
729
|
}
|
|
@@ -4059,6 +4060,9 @@ function validateProviderLoginInput(params) {
|
|
|
4059
4060
|
if (field.required && !normalized) {
|
|
4060
4061
|
return { ok: false, error: `Missing required field: ${field.name}` };
|
|
4061
4062
|
}
|
|
4063
|
+
if (normalized && field.options && !field.options.some((option) => option.value === normalized)) {
|
|
4064
|
+
return { ok: false, error: `Invalid value for ${field.name}: ${normalized}` };
|
|
4065
|
+
}
|
|
4062
4066
|
if (normalized) {
|
|
4063
4067
|
values[field.name] = normalized;
|
|
4064
4068
|
} else if (field.defaultValue) {
|
|
@@ -6521,6 +6525,60 @@ function parseServerLoaderRequest(payload) {
|
|
|
6521
6525
|
return JSON.parse(payload);
|
|
6522
6526
|
}
|
|
6523
6527
|
|
|
6528
|
+
// src/server/restrictedModelRegistry.ts
|
|
6529
|
+
var SERVER_MODE_ALLOWED_MODEL_IDS_BY_PROVIDER = {
|
|
6530
|
+
anthropic: [
|
|
6531
|
+
"claude-opus-4-6",
|
|
6532
|
+
"claude-sonnet-4-6",
|
|
6533
|
+
"claude-haiku-4-5"
|
|
6534
|
+
],
|
|
6535
|
+
openai: [
|
|
6536
|
+
"gpt-5.4",
|
|
6537
|
+
"gpt-5.4-mini",
|
|
6538
|
+
"gpt-5.4-nano"
|
|
6539
|
+
],
|
|
6540
|
+
"azure-openai-responses": [
|
|
6541
|
+
"gpt-5.4",
|
|
6542
|
+
"gpt-5.4-mini",
|
|
6543
|
+
"gpt-5.4-nano"
|
|
6544
|
+
]
|
|
6545
|
+
};
|
|
6546
|
+
var ALLOWED_MODEL_IDS_BY_PROVIDER = Object.fromEntries(
|
|
6547
|
+
Object.entries(SERVER_MODE_ALLOWED_MODEL_IDS_BY_PROVIDER).map(([provider, modelIds]) => [provider, new Set(modelIds)])
|
|
6548
|
+
);
|
|
6549
|
+
function isServerSelectableModel(model) {
|
|
6550
|
+
const allowedModelIds = ALLOWED_MODEL_IDS_BY_PROVIDER[model.provider];
|
|
6551
|
+
if (!allowedModelIds) {
|
|
6552
|
+
return true;
|
|
6553
|
+
}
|
|
6554
|
+
return allowedModelIds.has(model.id);
|
|
6555
|
+
}
|
|
6556
|
+
function filterModels(models) {
|
|
6557
|
+
return models.filter((model) => isServerSelectableModel(model));
|
|
6558
|
+
}
|
|
6559
|
+
function createServerRestrictedModelRegistry(modelRegistry) {
|
|
6560
|
+
return new Proxy(modelRegistry, {
|
|
6561
|
+
get(target, property, receiver) {
|
|
6562
|
+
if (property === "getAll") {
|
|
6563
|
+
return () => filterModels(target.getAll());
|
|
6564
|
+
}
|
|
6565
|
+
if (property === "getAvailable") {
|
|
6566
|
+
return () => filterModels(target.getAvailable());
|
|
6567
|
+
}
|
|
6568
|
+
if (property === "find") {
|
|
6569
|
+
return (provider, modelId) => {
|
|
6570
|
+
if (!isServerSelectableModel({ provider, id: modelId })) {
|
|
6571
|
+
return void 0;
|
|
6572
|
+
}
|
|
6573
|
+
return target.find(provider, modelId);
|
|
6574
|
+
};
|
|
6575
|
+
}
|
|
6576
|
+
const value = Reflect.get(target, property, receiver);
|
|
6577
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
6578
|
+
}
|
|
6579
|
+
});
|
|
6580
|
+
}
|
|
6581
|
+
|
|
6524
6582
|
// src/services/spinner.ts
|
|
6525
6583
|
var import_picocolors = __toESM(require_picocolors());
|
|
6526
6584
|
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
@@ -6679,6 +6737,17 @@ function createServerSessionAdapter(params) {
|
|
|
6679
6737
|
}
|
|
6680
6738
|
};
|
|
6681
6739
|
}
|
|
6740
|
+
async function ensureServerSelectableSessionModel(params) {
|
|
6741
|
+
const availableModels = params.modelRegistry.getAvailable();
|
|
6742
|
+
if (availableModels.length === 0) {
|
|
6743
|
+
return;
|
|
6744
|
+
}
|
|
6745
|
+
const currentModel = params.session.model;
|
|
6746
|
+
const currentModelIsSelectable = currentModel ? availableModels.some((model) => model.provider === currentModel.provider && model.id === currentModel.id) : false;
|
|
6747
|
+
if (!currentModelIsSelectable) {
|
|
6748
|
+
await params.session.setModel(availableModels[0]);
|
|
6749
|
+
}
|
|
6750
|
+
}
|
|
6682
6751
|
async function main() {
|
|
6683
6752
|
const request = readLoaderRequest();
|
|
6684
6753
|
const pi = await loadPiExports();
|
|
@@ -6697,7 +6766,7 @@ async function main() {
|
|
|
6697
6766
|
const authStorage = pi.AuthStorage.create((0, import_node_path7.join)(agentDir, "auth.json"));
|
|
6698
6767
|
const settingsManager = pi.SettingsManager.create(cwd, agentDir);
|
|
6699
6768
|
const modelsJsonPath = (0, import_node_path7.join)(agentDir, "models.json");
|
|
6700
|
-
const modelRegistry =
|
|
6769
|
+
const modelRegistry = createServerRestrictedModelRegistry(pi.ModelRegistry.create(authStorage, modelsJsonPath));
|
|
6701
6770
|
const quietStartup = !request.verbose;
|
|
6702
6771
|
if (quietStartup) {
|
|
6703
6772
|
process.env.PI_SKIP_VERSION_CHECK = "1";
|
|
@@ -6752,6 +6821,10 @@ async function main() {
|
|
|
6752
6821
|
if (hasPackagedMcpAdapter) {
|
|
6753
6822
|
extensionsResult.runtime.flagValues.set("mcp-config", mcpConfigPath);
|
|
6754
6823
|
}
|
|
6824
|
+
await ensureServerSelectableSessionModel({
|
|
6825
|
+
session,
|
|
6826
|
+
modelRegistry
|
|
6827
|
+
});
|
|
6755
6828
|
spinner.stop();
|
|
6756
6829
|
if (!session.model) {
|
|
6757
6830
|
throw new Error(
|
|
@@ -6799,6 +6872,10 @@ Or create ${modelsJsonPath}`
|
|
|
6799
6872
|
model: requestedModel,
|
|
6800
6873
|
thinkingLevel: request.thinking
|
|
6801
6874
|
});
|
|
6875
|
+
await ensureServerSelectableSessionModel({
|
|
6876
|
+
session: freshSession,
|
|
6877
|
+
modelRegistry
|
|
6878
|
+
});
|
|
6802
6879
|
return createServerSessionAdapter({
|
|
6803
6880
|
session: freshSession,
|
|
6804
6881
|
extensionsResult: freshExtensionsResult
|
|
@@ -6827,6 +6904,10 @@ Or create ${modelsJsonPath}`
|
|
|
6827
6904
|
model: requestedModel,
|
|
6828
6905
|
thinkingLevel: request.thinking
|
|
6829
6906
|
});
|
|
6907
|
+
await ensureServerSelectableSessionModel({
|
|
6908
|
+
session: resumedSession,
|
|
6909
|
+
modelRegistry
|
|
6910
|
+
});
|
|
6830
6911
|
return createServerSessionAdapter({
|
|
6831
6912
|
session: resumedSession,
|
|
6832
6913
|
extensionsResult: resumedExtensionsResult
|