@pasko70/pibo 3.2.7 → 3.4.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/agent-runtime/capabilities.js +5 -0
- package/dist/agent-runtime/contract.js +2 -0
- package/dist/agent-runtime/routed-session.js +68 -11
- package/dist/agent-runtimes/codex-native/adapter.js +4 -1
- package/dist/agent-runtimes/codex-native/process.js +1 -1
- package/dist/agent-runtimes/codex-native/protocol-version.js +6 -6
- package/dist/agent-runtimes/codex-native/thread.js +26 -4
- package/dist/agent-runtimes/omp/adapter.js +1 -0
- package/dist/agent-runtimes/omp/process.js +23 -3
- package/dist/agent-runtimes/omp/protocol-version.js +2 -0
- package/dist/agent-runtimes/pi/adapter.js +5 -1
- package/dist/agent-runtimes/pi/model-catalog.js +2 -2
- package/dist/agent-runtimes/pi/routed-session.js +53 -5
- package/dist/agent-runtimes/pi/runtime.js +6 -3
- package/dist/apps/chat/chat-api-routes.js +12 -38
- package/dist/apps/chat/chat-request-normalizers.js +15 -50
- package/dist/apps/chat/data/legacy-project-migration.js +492 -0
- package/dist/apps/chat/data/room-service.js +2 -2
- package/dist/apps/chat/data/workflow-session-model.js +1 -0
- package/dist/apps/chat/data/workflow-session-service.js +352 -0
- package/dist/apps/chat/rooms.js +1 -1
- package/dist/apps/chat/session-metadata.js +30 -0
- package/dist/apps/chat/trace.js +15 -2
- package/dist/apps/chat/types/rooms.js +30 -0
- package/dist/apps/chat/web-app.js +355 -651
- package/dist/apps/chat/workflow-catalog.js +18 -18
- package/dist/apps/chat/{project-workflow-human-actions.js → workflow-human-actions.js} +14 -14
- package/dist/apps/chat/workflow-manual-trigger-runtime.js +5 -1
- package/dist/apps/chat/workflow-persistence.js +20 -28
- package/dist/apps/chat/{project-workflow-sessions.js → workflow-sessions.js} +18 -17
- package/dist/apps/chat-ui/assets/{dist-ENXYFYda.js → dist-AhtdAETR.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CGgUuVB6.js → dist-Bk_L1qbJ.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-DG6T1maU.js → dist-Dyp6sLQn.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CFtZTGHa.js → dist-jVaiGXFD.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BikaGikn.js → dist-t25moyJS.js} +1 -1
- package/dist/apps/chat-ui/assets/index-CZjNw-aK.js +228 -0
- package/dist/apps/chat-ui/assets/index-CcEjFITM.css +1 -0
- package/dist/apps/chat-ui/index.html +2 -2
- package/dist/apps/chat-vscode-web/assets/index-Spj6M0tn.js +43 -0
- package/dist/apps/chat-vscode-web/index.html +1 -1
- package/dist/compute/pool/cli.js +1 -1
- package/dist/compute/pool/seeds.js +2 -3
- package/dist/config/config.js +1 -1
- package/dist/core/session-router.js +19 -10
- package/dist/debug/agents.js +9 -3
- package/dist/plugins/builtin.js +2 -0
- package/dist/plugins/registry.js +1 -0
- package/dist/previews/cli.js +154 -79
- package/dist/previews/compute-worker.js +37 -0
- package/dist/previews/config.js +2 -1
- package/dist/previews/migrations/session-ownership.js +7 -0
- package/dist/previews/proxy.js +4 -2
- package/dist/previews/public-setup.js +108 -0
- package/dist/previews/store.js +20 -13
- package/dist/previews/web-app.js +12 -2
- package/dist/providers/openai-gpt56.js +41 -3
- package/dist/sessions/workflow-session-kind.js +0 -3
- package/dist/subagents/context.js +2 -2
- package/dist/subagents/observation-query.js +49 -6
- package/dist/subagents/observation-text-regex.js +124 -0
- package/dist/subagents/tool.js +3 -2
- package/dist/tools/hashline.js +64 -0
- package/npm-shrinkwrap.json +786 -284
- package/package.json +11 -6
- package/packages/workflows/README.md +21 -0
- package/packages/workflows/dist/api/index.d.ts +48 -0
- package/packages/workflows/dist/api/index.d.ts.map +1 -0
- package/packages/workflows/dist/api/index.js +96 -0
- package/packages/workflows/dist/api/index.js.map +1 -0
- package/packages/workflows/dist/definition-hash.d.ts +4 -0
- package/packages/workflows/dist/definition-hash.d.ts.map +1 -0
- package/packages/workflows/dist/definition-hash.js +27 -0
- package/packages/workflows/dist/definition-hash.js.map +1 -0
- package/packages/workflows/dist/fixtures/index.d.ts +39 -0
- package/packages/workflows/dist/fixtures/index.d.ts.map +1 -0
- package/packages/workflows/dist/fixtures/index.js +608 -0
- package/packages/workflows/dist/fixtures/index.js.map +1 -0
- package/packages/workflows/dist/index.d.ts +16 -0
- package/packages/workflows/dist/index.d.ts.map +1 -0
- package/packages/workflows/dist/index.js +10 -0
- package/packages/workflows/dist/index.js.map +1 -0
- package/packages/workflows/dist/inspection/index.d.ts +47 -0
- package/packages/workflows/dist/inspection/index.d.ts.map +1 -0
- package/packages/workflows/dist/inspection/index.js +131 -0
- package/packages/workflows/dist/inspection/index.js.map +1 -0
- package/packages/workflows/dist/registry/index.d.ts +30 -0
- package/packages/workflows/dist/registry/index.d.ts.map +1 -0
- package/packages/workflows/dist/registry/index.js +161 -0
- package/packages/workflows/dist/registry/index.js.map +1 -0
- package/packages/workflows/dist/runtime/adapter-node.d.ts +28 -0
- package/packages/workflows/dist/runtime/adapter-node.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/adapter-node.js +172 -0
- package/packages/workflows/dist/runtime/adapter-node.js.map +1 -0
- package/packages/workflows/dist/runtime/agent-node.d.ts +32 -0
- package/packages/workflows/dist/runtime/agent-node.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/agent-node.js +231 -0
- package/packages/workflows/dist/runtime/agent-node.js.map +1 -0
- package/packages/workflows/dist/runtime/agent-runtime.d.ts +25 -0
- package/packages/workflows/dist/runtime/agent-runtime.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/agent-runtime.js +111 -0
- package/packages/workflows/dist/runtime/agent-runtime.js.map +1 -0
- package/packages/workflows/dist/runtime/code-node.d.ts +31 -0
- package/packages/workflows/dist/runtime/code-node.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/code-node.js +223 -0
- package/packages/workflows/dist/runtime/code-node.js.map +1 -0
- package/packages/workflows/dist/runtime/dispatch-failures.d.ts +36 -0
- package/packages/workflows/dist/runtime/dispatch-failures.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/dispatch-failures.js +80 -0
- package/packages/workflows/dist/runtime/dispatch-failures.js.map +1 -0
- package/packages/workflows/dist/runtime/edge-payloads.d.ts +3 -0
- package/packages/workflows/dist/runtime/edge-payloads.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/edge-payloads.js +11 -0
- package/packages/workflows/dist/runtime/edge-payloads.js.map +1 -0
- package/packages/workflows/dist/runtime/edge-transfer.d.ts +39 -0
- package/packages/workflows/dist/runtime/edge-transfer.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/edge-transfer.js +356 -0
- package/packages/workflows/dist/runtime/edge-transfer.js.map +1 -0
- package/packages/workflows/dist/runtime/human-action.d.ts +43 -0
- package/packages/workflows/dist/runtime/human-action.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/human-action.js +231 -0
- package/packages/workflows/dist/runtime/human-action.js.map +1 -0
- package/packages/workflows/dist/runtime/human-node.d.ts +27 -0
- package/packages/workflows/dist/runtime/human-node.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/human-node.js +126 -0
- package/packages/workflows/dist/runtime/human-node.js.map +1 -0
- package/packages/workflows/dist/runtime/ids.d.ts +2 -0
- package/packages/workflows/dist/runtime/ids.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/ids.js +4 -0
- package/packages/workflows/dist/runtime/ids.js.map +1 -0
- package/packages/workflows/dist/runtime/index.d.ts +23 -0
- package/packages/workflows/dist/runtime/index.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/index.js +12 -0
- package/packages/workflows/dist/runtime/index.js.map +1 -0
- package/packages/workflows/dist/runtime/manual-trigger.d.ts +51 -0
- package/packages/workflows/dist/runtime/manual-trigger.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/manual-trigger.js +403 -0
- package/packages/workflows/dist/runtime/manual-trigger.js.map +1 -0
- package/packages/workflows/dist/runtime/nested-workflow-node.d.ts +48 -0
- package/packages/workflows/dist/runtime/nested-workflow-node.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/nested-workflow-node.js +246 -0
- package/packages/workflows/dist/runtime/nested-workflow-node.js.map +1 -0
- package/packages/workflows/dist/runtime/one-node-agent.d.ts +34 -0
- package/packages/workflows/dist/runtime/one-node-agent.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/one-node-agent.js +334 -0
- package/packages/workflows/dist/runtime/one-node-agent.js.map +1 -0
- package/packages/workflows/dist/runtime/persistence.d.ts +9 -0
- package/packages/workflows/dist/runtime/persistence.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/persistence.js +67 -0
- package/packages/workflows/dist/runtime/persistence.js.map +1 -0
- package/packages/workflows/dist/runtime/pibo-routing.d.ts +126 -0
- package/packages/workflows/dist/runtime/pibo-routing.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/pibo-routing.js +96 -0
- package/packages/workflows/dist/runtime/pibo-routing.js.map +1 -0
- package/packages/workflows/dist/runtime/prompts.d.ts +20 -0
- package/packages/workflows/dist/runtime/prompts.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/prompts.js +235 -0
- package/packages/workflows/dist/runtime/prompts.js.map +1 -0
- package/packages/workflows/dist/runtime/retry.d.ts +35 -0
- package/packages/workflows/dist/runtime/retry.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/retry.js +80 -0
- package/packages/workflows/dist/runtime/retry.js.map +1 -0
- package/packages/workflows/dist/runtime/state.d.ts +14 -0
- package/packages/workflows/dist/runtime/state.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/state.js +139 -0
- package/packages/workflows/dist/runtime/state.js.map +1 -0
- package/packages/workflows/dist/runtime/time.d.ts +6 -0
- package/packages/workflows/dist/runtime/time.d.ts.map +1 -0
- package/packages/workflows/dist/runtime/time.js +42 -0
- package/packages/workflows/dist/runtime/time.js.map +1 -0
- package/packages/workflows/dist/store/catalog-records.d.ts +18 -0
- package/packages/workflows/dist/store/catalog-records.d.ts.map +1 -0
- package/packages/workflows/dist/store/catalog-records.js +59 -0
- package/packages/workflows/dist/store/catalog-records.js.map +1 -0
- package/packages/workflows/dist/store/contracts.d.ts +149 -0
- package/packages/workflows/dist/store/contracts.d.ts.map +1 -0
- package/packages/workflows/dist/store/contracts.js +2 -0
- package/packages/workflows/dist/store/contracts.js.map +1 -0
- package/packages/workflows/dist/store/draft-writes.d.ts +7 -0
- package/packages/workflows/dist/store/draft-writes.d.ts.map +1 -0
- package/packages/workflows/dist/store/draft-writes.js +18 -0
- package/packages/workflows/dist/store/draft-writes.js.map +1 -0
- package/packages/workflows/dist/store/index.d.ts +55 -0
- package/packages/workflows/dist/store/index.d.ts.map +1 -0
- package/packages/workflows/dist/store/index.js +650 -0
- package/packages/workflows/dist/store/index.js.map +1 -0
- package/packages/workflows/dist/store/list-query.d.ts +13 -0
- package/packages/workflows/dist/store/list-query.d.ts.map +1 -0
- package/packages/workflows/dist/store/list-query.js +20 -0
- package/packages/workflows/dist/store/list-query.js.map +1 -0
- package/packages/workflows/dist/store/row-mappers.d.ts +206 -0
- package/packages/workflows/dist/store/row-mappers.d.ts.map +1 -0
- package/packages/workflows/dist/store/row-mappers.js +262 -0
- package/packages/workflows/dist/store/row-mappers.js.map +1 -0
- package/packages/workflows/dist/store/schema.d.ts +13 -0
- package/packages/workflows/dist/store/schema.d.ts.map +1 -0
- package/packages/workflows/dist/store/schema.js +458 -0
- package/packages/workflows/dist/store/schema.js.map +1 -0
- package/packages/workflows/dist/store/write-values.d.ts +18 -0
- package/packages/workflows/dist/store/write-values.d.ts.map +1 -0
- package/packages/workflows/dist/store/write-values.js +227 -0
- package/packages/workflows/dist/store/write-values.js.map +1 -0
- package/packages/workflows/dist/types/index.d.ts +1202 -0
- package/packages/workflows/dist/types/index.d.ts.map +1 -0
- package/packages/workflows/dist/types/index.js +8 -0
- package/packages/workflows/dist/types/index.js.map +1 -0
- package/packages/workflows/dist/validation/diagnostics.d.ts +27 -0
- package/packages/workflows/dist/validation/diagnostics.d.ts.map +1 -0
- package/packages/workflows/dist/validation/diagnostics.js +104 -0
- package/packages/workflows/dist/validation/diagnostics.js.map +1 -0
- package/packages/workflows/dist/validation/graph-cycles.d.ts +4 -0
- package/packages/workflows/dist/validation/graph-cycles.d.ts.map +1 -0
- package/packages/workflows/dist/validation/graph-cycles.js +130 -0
- package/packages/workflows/dist/validation/graph-cycles.js.map +1 -0
- package/packages/workflows/dist/validation/graph-edges.d.ts +5 -0
- package/packages/workflows/dist/validation/graph-edges.d.ts.map +1 -0
- package/packages/workflows/dist/validation/graph-edges.js +48 -0
- package/packages/workflows/dist/validation/graph-edges.js.map +1 -0
- package/packages/workflows/dist/validation/graph-ports.d.ts +5 -0
- package/packages/workflows/dist/validation/graph-ports.d.ts.map +1 -0
- package/packages/workflows/dist/validation/graph-ports.js +55 -0
- package/packages/workflows/dist/validation/graph-ports.js.map +1 -0
- package/packages/workflows/dist/validation/index.d.ts +18 -0
- package/packages/workflows/dist/validation/index.d.ts.map +1 -0
- package/packages/workflows/dist/validation/index.js +175 -0
- package/packages/workflows/dist/validation/index.js.map +1 -0
- package/packages/workflows/dist/validation/json-schema.d.ts +12 -0
- package/packages/workflows/dist/validation/json-schema.d.ts.map +1 -0
- package/packages/workflows/dist/validation/json-schema.js +556 -0
- package/packages/workflows/dist/validation/json-schema.js.map +1 -0
- package/packages/workflows/dist/validation/registry-refs.d.ts +21 -0
- package/packages/workflows/dist/validation/registry-refs.d.ts.map +1 -0
- package/packages/workflows/dist/validation/registry-refs.js +283 -0
- package/packages/workflows/dist/validation/registry-refs.js.map +1 -0
- package/packages/workflows/dist/validation/retry-policy.d.ts +3 -0
- package/packages/workflows/dist/validation/retry-policy.d.ts.map +1 -0
- package/packages/workflows/dist/validation/retry-policy.js +114 -0
- package/packages/workflows/dist/validation/retry-policy.js.map +1 -0
- package/packages/workflows/dist/validation/schema-declarations.d.ts +5 -0
- package/packages/workflows/dist/validation/schema-declarations.d.ts.map +1 -0
- package/packages/workflows/dist/validation/schema-declarations.js +36 -0
- package/packages/workflows/dist/validation/schema-declarations.js.map +1 -0
- package/packages/workflows/dist/validation/state-access.d.ts +4 -0
- package/packages/workflows/dist/validation/state-access.d.ts.map +1 -0
- package/packages/workflows/dist/validation/state-access.js +121 -0
- package/packages/workflows/dist/validation/state-access.js.map +1 -0
- package/packages/workflows/dist/xstate/index.d.ts +73 -0
- package/packages/workflows/dist/xstate/index.d.ts.map +1 -0
- package/packages/workflows/dist/xstate/index.js +728 -0
- package/packages/workflows/dist/xstate/index.js.map +1 -0
- package/packages/workflows/package.json +23 -0
- package/dist/apps/chat/data/project-service.js +0 -1029
- package/dist/apps/chat-ui/assets/index-BwT5grLv.css +0 -1
- package/dist/apps/chat-ui/assets/index-PTJanD3E.js +0 -228
- package/dist/apps/chat-vscode-web/assets/index-D1bpAUkR.js +0 -43
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<meta name="theme-color" content="#101d22" />
|
|
7
7
|
<title>Pibo</title>
|
|
8
|
-
<script type="module" crossorigin src="/apps/chat-vscode/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/apps/chat-vscode/assets/index-Spj6M0tn.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/apps/chat-vscode/assets/index-b18ZkEo0.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/dist/compute/pool/cli.js
CHANGED
|
@@ -149,7 +149,7 @@ Provide exactly one source:
|
|
|
149
149
|
program.command("seed")
|
|
150
150
|
.action(() => console.log(`Deployment seed modes:
|
|
151
151
|
full Nearly complete Pibo home plus configured workspace; excludes active runtime, lock, browser, debug, and pool state.
|
|
152
|
-
medium Operational config, selected product databases,
|
|
152
|
+
medium Operational config, selected product and workflow databases, contexts, agents, and user skills; excludes heavy payload/tool/browser/debug state.
|
|
153
153
|
fresh Operational config, Google/Machine auth configuration, model defaults, contexts, and user skills; no existing product databases.
|
|
154
154
|
`));
|
|
155
155
|
await program.parseAsync(argv);
|
|
@@ -35,11 +35,10 @@ const MEDIUM_ALLOWED_TOP_LEVEL = new Set([
|
|
|
35
35
|
"chat-agents.sqlite",
|
|
36
36
|
"pibo.sqlite",
|
|
37
37
|
"pibo-events.sqlite",
|
|
38
|
-
"
|
|
38
|
+
"pibo-workflows.sqlite",
|
|
39
39
|
"web-annotations.sqlite",
|
|
40
40
|
"context-files",
|
|
41
41
|
"user-skills",
|
|
42
|
-
"projects",
|
|
43
42
|
]);
|
|
44
43
|
const FRESH_ALLOWED_TOP_LEVEL = new Set([
|
|
45
44
|
"config.json",
|
|
@@ -137,7 +136,7 @@ async function backupSeedDatabases(sourceHome, destinationHome, mode) {
|
|
|
137
136
|
if (mode === "fresh")
|
|
138
137
|
return [];
|
|
139
138
|
const allowed = mode === "medium"
|
|
140
|
-
? new Set(["chat-agents.sqlite", "pibo.sqlite", "pibo-events.sqlite", "
|
|
139
|
+
? new Set(["chat-agents.sqlite", "pibo.sqlite", "pibo-events.sqlite", "pibo-workflows.sqlite", "web-annotations.sqlite"])
|
|
141
140
|
: undefined;
|
|
142
141
|
const copied = [];
|
|
143
142
|
for (const entry of await readdir(sourceHome, { withFileTypes: true })) {
|
package/dist/config/config.js
CHANGED
|
@@ -59,7 +59,7 @@ export const PIBO_CONFIG_KEYS = [
|
|
|
59
59
|
{
|
|
60
60
|
key: "preview.baseURL",
|
|
61
61
|
type: "string",
|
|
62
|
-
description: "Public
|
|
62
|
+
description: "Public Preview base URL. Run `pibo preview setup --base-url https://preview.example.com` before enabling it.",
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
key: "preview.databasePath",
|
|
@@ -231,7 +231,6 @@ function derivedSessionMetadata(value) {
|
|
|
231
231
|
for (const key of [
|
|
232
232
|
DERIVED_SESSION_RECONCILIATION_METADATA_KEY,
|
|
233
233
|
"workflowSessionKind",
|
|
234
|
-
"projectSessionKind",
|
|
235
234
|
"subagentName",
|
|
236
235
|
"subagentToolName",
|
|
237
236
|
"agentStatus",
|
|
@@ -1692,9 +1691,13 @@ export class PiboSessionRouter {
|
|
|
1692
1691
|
catch (error) {
|
|
1693
1692
|
transitionError = error;
|
|
1694
1693
|
}
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1694
|
+
if (result.sourceSessionUnchanged) {
|
|
1695
|
+
if (transitionError)
|
|
1696
|
+
throw transitionError;
|
|
1697
|
+
return;
|
|
1698
|
+
}
|
|
1699
|
+
// Identity-moving forks and clones transfer the live native handle to the
|
|
1700
|
+
// derived session, so the source must be reopened from its persisted binding.
|
|
1698
1701
|
try {
|
|
1699
1702
|
await this.resetCachedSession(event.piboSessionId);
|
|
1700
1703
|
}
|
|
@@ -2090,12 +2093,18 @@ export class PiboSessionRouter {
|
|
|
2090
2093
|
for (const agentId of input.agentIds ?? [])
|
|
2091
2094
|
this.requireManagedAgent(parentPiboSessionId, agentId);
|
|
2092
2095
|
const query = preparePiboAgentObservationQuery(input);
|
|
2093
|
-
const
|
|
2094
|
-
|
|
2095
|
-
:
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2096
|
+
const observations = this.agentObservations;
|
|
2097
|
+
function* ordered() {
|
|
2098
|
+
const start = query.scanOrder === "asc" ? 0 : observations.length - 1;
|
|
2099
|
+
const end = query.scanOrder === "asc" ? observations.length : -1;
|
|
2100
|
+
const step = query.scanOrder === "asc" ? 1 : -1;
|
|
2101
|
+
for (let index = start; index !== end; index += step) {
|
|
2102
|
+
const { managingParentId, ...observation } = observations[index];
|
|
2103
|
+
if (managingParentId === parentPiboSessionId)
|
|
2104
|
+
yield observation;
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
return selectPiboAgentObservationPage(ordered(), query, { evictedThrough: this.agentObservationEvictedThroughByParent.get(parentPiboSessionId) ?? 0 });
|
|
2099
2108
|
}
|
|
2100
2109
|
async killManagedAgent(parentPiboSessionId, agentId) {
|
|
2101
2110
|
const child = this.requireManagedAgent(parentPiboSessionId, agentId);
|
package/dist/debug/agents.js
CHANGED
|
@@ -47,6 +47,7 @@ export async function runDebugAgentsCli(args) {
|
|
|
47
47
|
since: parsed.since,
|
|
48
48
|
until: parsed.until,
|
|
49
49
|
textContains: parsed.textContains,
|
|
50
|
+
textRegex: parsed.textRegex,
|
|
50
51
|
afterSequence: parsed.afterSequence,
|
|
51
52
|
order: parsed.order,
|
|
52
53
|
limit: parsed.limit,
|
|
@@ -282,7 +283,7 @@ Filters use exact values. The command inspects only direct pibo.subagents childr
|
|
|
282
283
|
Usage:
|
|
283
284
|
pibo debug agents ${parentPiboSessionId} observe [--tool-call-id id] [--agent-id ps_...] [--name name]
|
|
284
285
|
[--thread-key key] [--event-type type] [--kind message|thinking|tool|error|lifecycle|event]
|
|
285
|
-
[--role role] [--since iso] [--until iso] [--contains text] [--after-sequence n]
|
|
286
|
+
[--role role] [--since iso] [--until iso] [--contains text] [--regex pattern] [--after-sequence n]
|
|
286
287
|
[--order asc|desc] [--limit 1..200] [--include-tools]
|
|
287
288
|
[--tool-detail summary|full] [--details] [--json]
|
|
288
289
|
|
|
@@ -290,7 +291,9 @@ Default: the newest 20 completed assistant messages, with streaming deltas and t
|
|
|
290
291
|
Use --include-tools for compact tool calls and terminal results. Explicit --event-type or --kind
|
|
291
292
|
filters retain access to progress events. Repeat plural filters for OR within that field.
|
|
292
293
|
Different fields combine with AND. With --after-sequence, pages always consume the oldest unseen rows;
|
|
293
|
-
--order desc reverses only the returned page, so nextAfterSequence remains safe for polling
|
|
294
|
+
--order desc reverses only the returned page, so nextAfterSequence remains safe for polling.
|
|
295
|
+
--regex uses case-sensitive bundled rg/Rust-regex syntax; inline flags change case or multiline behavior.
|
|
296
|
+
Regex rejects NUL text and literal or escaped NUL patterns and requires the optional rg platform binary.`);
|
|
294
297
|
}
|
|
295
298
|
function parseAgentDebugOptions(args) {
|
|
296
299
|
const parsed = {
|
|
@@ -350,6 +353,8 @@ function parseAgentDebugOptions(args) {
|
|
|
350
353
|
parsed.until = value;
|
|
351
354
|
else if (arg === "--contains")
|
|
352
355
|
parsed.textContains = value;
|
|
356
|
+
else if (arg === "--regex")
|
|
357
|
+
parsed.textRegex = value;
|
|
353
358
|
else if (arg === "--after-sequence")
|
|
354
359
|
parsed.afterSequence = parseNonNegativeInteger(value, arg);
|
|
355
360
|
else if (arg === "--order") {
|
|
@@ -377,7 +382,8 @@ function validateAgentDebugOptions(command, parsed) {
|
|
|
377
382
|
if (parsed.details || parsed.includeTools || parsed.toolCallIds.length > 0 || parsed.agentIds.length > 0
|
|
378
383
|
|| parsed.threadKeys.length > 0 || parsed.eventTypes.length > 0 || parsed.kinds.length > 0
|
|
379
384
|
|| parsed.roles.length > 0 || parsed.since !== undefined || parsed.until !== undefined
|
|
380
|
-
|| parsed.textContains !== undefined || parsed.
|
|
385
|
+
|| parsed.textContains !== undefined || parsed.textRegex !== undefined
|
|
386
|
+
|| parsed.afterSequence !== undefined || parsed.order !== undefined
|
|
381
387
|
|| parsed.limit !== undefined || parsed.toolDetail !== undefined)
|
|
382
388
|
throw new Error("Unsupported option for pibo debug agents list. Run the list command with --help.");
|
|
383
389
|
return;
|
package/dist/plugins/builtin.js
CHANGED
|
@@ -7,6 +7,7 @@ import { parsePiboThinkingLevel } from "../core/thinking.js";
|
|
|
7
7
|
import { createWebSearchToolProfile } from "../tools/web-search.js";
|
|
8
8
|
import { CODEX_BROWSER_TOOL_NAMES, createCodexBrowserToolProfiles } from "../tools/codex-browser.js";
|
|
9
9
|
import { createRuntimeToolProfile } from "../tools/runtime/tool.js";
|
|
10
|
+
import { createHashlineToolProfile } from "../tools/hashline.js";
|
|
10
11
|
import { loadModelCatalog } from "../apps/chat/model-catalog.js";
|
|
11
12
|
import { piboCodexCompatPlugin } from "./codex-compat.js";
|
|
12
13
|
import { piboCodexNativePlugin } from "./codex-native.js";
|
|
@@ -213,6 +214,7 @@ export const piboCorePlugin = definePiboPlugin({
|
|
|
213
214
|
});
|
|
214
215
|
api.registerTool(createWebSearchToolProfile());
|
|
215
216
|
api.registerTool(createRuntimeToolProfile());
|
|
217
|
+
api.registerTool(createHashlineToolProfile());
|
|
216
218
|
api.registerTools(createCodexBrowserToolProfiles());
|
|
217
219
|
api.registerCapabilityPackage({
|
|
218
220
|
name: "codex-browser-interface",
|
package/dist/plugins/registry.js
CHANGED
|
@@ -553,6 +553,7 @@ export class PiboPluginRegistry {
|
|
|
553
553
|
yieldable: tool.yieldable !== false,
|
|
554
554
|
hasDefinition: tool.definition !== undefined || tool.createDefinition !== undefined,
|
|
555
555
|
portable: toolIsPortable(tool),
|
|
556
|
+
...(tool.replacesBuiltinTools?.length ? { replacesBuiltinTools: [...tool.replacesBuiltinTools] } : {}),
|
|
556
557
|
pluginId: tool.pluginId,
|
|
557
558
|
pluginName: tool.pluginId ? this.pluginNames.get(tool.pluginId) : undefined,
|
|
558
559
|
...(tool.providerTool ? { providerTool: tool.providerTool } : {}),
|
package/dist/previews/cli.js
CHANGED
|
@@ -2,11 +2,13 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import { createDefaultPiboDataSessionStore } from "../sessions/pibo-data-store.js";
|
|
5
|
+
import { resolvePreviewComputeWorkerTarget } from "./compute-worker.js";
|
|
5
6
|
import { DEFAULT_PREVIEW_TTL_MINUTES, loadEffectivePreviewServerSettings, loadPreviewConfig, previewPublicURL, requirePreviewBaseURL } from "./config.js";
|
|
6
7
|
import { reconcileManagedPreviews, startManagedPreview, stopManagedPreview, validatePreviewStartCommand, } from "./manager.js";
|
|
7
8
|
import { findPreviewTargetProcess, isPiboControlProcess, isPiboYieldedProcess, isPreviewTargetProcessCurrent, probePreviewTarget, validatePreviewPort, } from "./network.js";
|
|
8
9
|
import { createDefaultPreviewStore, previewExposureState } from "./store.js";
|
|
9
10
|
import { DEFAULT_MAX_PREVIEW_PROXY_CONNECTIONS, DEFAULT_MAX_PREVIEW_PROXY_CONNECTIONS_PER_PREVIEW, } from "./proxy.js";
|
|
11
|
+
import { createPreviewProductionSetupPlan, inspectPreviewPublicRoute } from "./public-setup.js";
|
|
10
12
|
function printJson(value) {
|
|
11
13
|
console.log(JSON.stringify(value, null, 2));
|
|
12
14
|
}
|
|
@@ -19,6 +21,12 @@ function parsePositiveInteger(value) {
|
|
|
19
21
|
throw new Error("Value must be a positive integer");
|
|
20
22
|
return parsed;
|
|
21
23
|
}
|
|
24
|
+
function parseGatewayPort(value) {
|
|
25
|
+
const parsed = Number(value);
|
|
26
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > 65535)
|
|
27
|
+
throw new Error("Gateway port must be an integer between 1 and 65535");
|
|
28
|
+
return parsed;
|
|
29
|
+
}
|
|
22
30
|
function parsePreviewTtlMinutes(value) {
|
|
23
31
|
const parsed = parsePositiveInteger(value);
|
|
24
32
|
if (parsed > 7 * 24 * 60)
|
|
@@ -28,12 +36,6 @@ function parsePreviewTtlMinutes(value) {
|
|
|
28
36
|
function createPreviewId() {
|
|
29
37
|
return `pv-${randomBytes(9).toString("hex")}`;
|
|
30
38
|
}
|
|
31
|
-
function inferredProjectId(metadata) {
|
|
32
|
-
if (!metadata || typeof metadata !== "object" || Array.isArray(metadata))
|
|
33
|
-
return undefined;
|
|
34
|
-
const projectId = metadata.projectId;
|
|
35
|
-
return typeof projectId === "string" && projectId.trim() ? projectId.trim() : undefined;
|
|
36
|
-
}
|
|
37
39
|
async function previewHealth(exposure) {
|
|
38
40
|
const state = previewExposureState(exposure);
|
|
39
41
|
if (state !== "active")
|
|
@@ -64,23 +66,117 @@ async function exposureView(exposure) {
|
|
|
64
66
|
...(target ? { latencyMs: target.latencyMs } : {}),
|
|
65
67
|
};
|
|
66
68
|
}
|
|
69
|
+
async function createPreviewExposure(port, options, defaults = {}) {
|
|
70
|
+
const baseURL = requirePreviewBaseURL();
|
|
71
|
+
const piboSessionId = options.session.trim();
|
|
72
|
+
if (!piboSessionId)
|
|
73
|
+
throw new Error("--session must contain a Pibo Session ID");
|
|
74
|
+
const sessionStore = createDefaultPiboDataSessionStore();
|
|
75
|
+
let session;
|
|
76
|
+
try {
|
|
77
|
+
session = sessionStore.get(piboSessionId);
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
sessionStore.close();
|
|
81
|
+
}
|
|
82
|
+
if (!session)
|
|
83
|
+
throw new Error(`Pibo Session "${piboSessionId}" was not found`);
|
|
84
|
+
const command = options.command === undefined ? undefined : validatePreviewStartCommand(options.command);
|
|
85
|
+
const target = command ? undefined : await probePreviewTarget(port);
|
|
86
|
+
if (!command && !target)
|
|
87
|
+
throw new Error(`No development server is reachable on loopback port ${port}`);
|
|
88
|
+
if (command && await probePreviewTarget(port, { timeoutMs: 150 }))
|
|
89
|
+
throw new Error(`Preview port ${port} is already occupied`);
|
|
90
|
+
const now = new Date();
|
|
91
|
+
const id = createPreviewId();
|
|
92
|
+
const targetProcess = target ? findPreviewTargetProcess(target.host, port) : undefined;
|
|
93
|
+
if (!command && process.platform === "linux" && !targetProcess) {
|
|
94
|
+
throw new Error(`Preview port ${port} is not bound exclusively to the selected loopback address`);
|
|
95
|
+
}
|
|
96
|
+
if (!command && targetProcess && isPiboControlProcess(targetProcess.pid)) {
|
|
97
|
+
throw new Error(`Preview port ${port} belongs to a Pibo control process and cannot be exposed`);
|
|
98
|
+
}
|
|
99
|
+
if (!command && process.env.NODE_ENV !== "test" && targetProcess && isPiboYieldedProcess(targetProcess.pid)) {
|
|
100
|
+
throw new Error("Preview servers cannot run as yielded agent resources; stop that process and use --command so Preview owns its lifecycle");
|
|
101
|
+
}
|
|
102
|
+
const store = createDefaultPreviewStore();
|
|
103
|
+
let exposure;
|
|
104
|
+
try {
|
|
105
|
+
exposure = store.createExposure({
|
|
106
|
+
id,
|
|
107
|
+
piboSessionId,
|
|
108
|
+
label: options.name?.trim() || defaults.label || `Preview ${port}`,
|
|
109
|
+
targetHost: target?.host ?? "127.0.0.1",
|
|
110
|
+
targetPort: port,
|
|
111
|
+
targetProcessId: targetProcess?.pid,
|
|
112
|
+
targetProcessStartTicks: targetProcess?.startTicks,
|
|
113
|
+
workspace: resolve(options.workspace ?? defaults.workspace ?? session.workspace ?? process.cwd()),
|
|
114
|
+
managementMode: command ? "managed" : "external",
|
|
115
|
+
proxyMode: defaults.proxyMode,
|
|
116
|
+
startCommand: command,
|
|
117
|
+
serverState: command ? "stopped" : undefined,
|
|
118
|
+
createdAt: now.toISOString(),
|
|
119
|
+
expiresAt: new Date(now.getTime() + options.ttlMinutes * 60_000).toISOString(),
|
|
120
|
+
});
|
|
121
|
+
if (command)
|
|
122
|
+
exposure = await startManagedPreview(store, id);
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
store.close();
|
|
126
|
+
}
|
|
127
|
+
return { ...await exposureView(exposure), publicUrl: previewPublicURL(id, baseURL).toString() };
|
|
128
|
+
}
|
|
129
|
+
function printCreatedPreview(result, json = false) {
|
|
130
|
+
if (json) {
|
|
131
|
+
printJson(result);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
console.log(`${result.id}\t${result.health}\t${result.label}`);
|
|
135
|
+
console.log(`url\t${result.publicUrl}`);
|
|
136
|
+
console.log(`session\t${result.piboSessionId}`);
|
|
137
|
+
console.log(`managed\t${result.managed}`);
|
|
138
|
+
console.log(`proxyMode\t${result.proxyMode}`);
|
|
139
|
+
if (result.serverStopAt)
|
|
140
|
+
console.log(`autoStop\t${result.serverStopAt}`);
|
|
141
|
+
console.log(`expires\t${result.expiresAt}`);
|
|
142
|
+
}
|
|
67
143
|
function printPreviewDiscovery() {
|
|
68
144
|
console.log(`pibo preview - Session-linked live development previews
|
|
69
145
|
|
|
70
146
|
Commands:
|
|
147
|
+
setup Print production DNS, TLS, proxy, and restart instructions
|
|
71
148
|
expose <port> Register an external port or start a managed server with --command
|
|
149
|
+
expose-worker <id> Register a running Pibo compute worker with local dev auth
|
|
72
150
|
list List preview registrations
|
|
73
151
|
show <preview-id> Inspect one preview
|
|
74
152
|
start <preview-id> Start a saved managed Preview server
|
|
75
153
|
stop <preview-id> Stop a managed Preview server without removing it
|
|
76
|
-
doctor [preview-id] Check
|
|
154
|
+
doctor [preview-id] Check local state; add --public to verify DNS, TLS, and routing
|
|
77
155
|
remove <preview-id> Stop and remove a preview definition
|
|
78
156
|
close <preview-id> Alias for remove
|
|
79
157
|
|
|
80
158
|
Next:
|
|
159
|
+
pibo preview setup --help
|
|
81
160
|
pibo preview expose --help
|
|
161
|
+
pibo preview expose-worker --help
|
|
82
162
|
`);
|
|
83
163
|
}
|
|
164
|
+
function printProductionSetupPlan(plan) {
|
|
165
|
+
console.log("Preview production setup");
|
|
166
|
+
console.log(`baseURL\t${plan.baseURL}`);
|
|
167
|
+
console.log(`DNS\t${plan.dnsRecord.type} ${plan.dnsRecord.name} -> ${plan.dnsRecord.value}`);
|
|
168
|
+
console.log("\nCaddy global options (merge into an existing global block):");
|
|
169
|
+
console.log(plan.caddy.globalOptions);
|
|
170
|
+
console.log("\nCaddy site block:");
|
|
171
|
+
console.log(plan.caddy.siteBlock);
|
|
172
|
+
console.log("\nCommands:");
|
|
173
|
+
console.log(`configure\t${plan.commands.configure}`);
|
|
174
|
+
console.log(`validate proxy\t${plan.commands.validateCaddy}`);
|
|
175
|
+
console.log(`restart gateway\t${plan.commands.restartGateway}`);
|
|
176
|
+
console.log(`verify\t${plan.commands.verify}`);
|
|
177
|
+
for (const warning of plan.warnings)
|
|
178
|
+
console.log(`warning\t${warning}`);
|
|
179
|
+
}
|
|
84
180
|
export async function runPreviewCli(argv = process.argv) {
|
|
85
181
|
if (argv.length <= 2 || argv[2] === "--help" || argv[2] === "-h") {
|
|
86
182
|
printPreviewDiscovery();
|
|
@@ -88,86 +184,51 @@ export async function runPreviewCli(argv = process.argv) {
|
|
|
88
184
|
}
|
|
89
185
|
const program = new Command();
|
|
90
186
|
program.name("pibo preview").description("Manage session-linked live development previews");
|
|
187
|
+
program
|
|
188
|
+
.command("setup")
|
|
189
|
+
.requiredOption("--base-url <url>", "Dedicated HTTPS base URL whose subdomains host Previews")
|
|
190
|
+
.option("--gateway-port <port>", "Loopback Pibo Web Gateway port", parseGatewayPort, 4788)
|
|
191
|
+
.option("--public-ip <address>", "Public IPv4 or IPv6 address for the exact DNS record")
|
|
192
|
+
.option("--json", "Print JSON")
|
|
193
|
+
.action((options) => {
|
|
194
|
+
const plan = createPreviewProductionSetupPlan({
|
|
195
|
+
baseURL: options.baseUrl,
|
|
196
|
+
gatewayPort: options.gatewayPort,
|
|
197
|
+
publicIp: options.publicIp,
|
|
198
|
+
});
|
|
199
|
+
if (options.json)
|
|
200
|
+
printJson(plan);
|
|
201
|
+
else
|
|
202
|
+
printProductionSetupPlan(plan);
|
|
203
|
+
});
|
|
91
204
|
program
|
|
92
205
|
.command("expose")
|
|
93
206
|
.argument("<port>", "Reachable loopback development port", parsePort)
|
|
94
207
|
.requiredOption("--session <pibo-session-id>", "Pibo Session that owns the preview")
|
|
95
|
-
.option("--project <project-id>", "Optional Project association")
|
|
96
208
|
.option("--name <label>", "Preview label")
|
|
97
209
|
.option("--workspace <path>", "Workspace used by the managed command and recorded for diagnostics")
|
|
98
210
|
.option("--command <shell-command>", "Save and start this command as a Preview-managed server")
|
|
99
211
|
.option("--ttl-minutes <minutes>", "Automatic preview-definition lifetime", parsePreviewTtlMinutes, DEFAULT_PREVIEW_TTL_MINUTES)
|
|
100
212
|
.option("--json", "Print JSON")
|
|
101
213
|
.action(async (port, options) => {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (command && await probePreviewTarget(port, { timeoutMs: 150 }))
|
|
121
|
-
throw new Error(`Preview port ${port} is already occupied`);
|
|
122
|
-
const now = new Date();
|
|
123
|
-
const id = createPreviewId();
|
|
124
|
-
const targetProcess = target ? findPreviewTargetProcess(target.host, port) : undefined;
|
|
125
|
-
if (!command && process.platform === "linux" && !targetProcess) {
|
|
126
|
-
throw new Error(`Preview port ${port} is not bound exclusively to the selected loopback address`);
|
|
127
|
-
}
|
|
128
|
-
if (!command && targetProcess && isPiboControlProcess(targetProcess.pid)) {
|
|
129
|
-
throw new Error(`Preview port ${port} belongs to a Pibo control process and cannot be exposed`);
|
|
130
|
-
}
|
|
131
|
-
if (!command && process.env.NODE_ENV !== "test" && targetProcess && isPiboYieldedProcess(targetProcess.pid)) {
|
|
132
|
-
throw new Error("Preview servers cannot run as yielded agent resources; stop that process and use --command so Preview owns its lifecycle");
|
|
133
|
-
}
|
|
134
|
-
const store = createDefaultPreviewStore();
|
|
135
|
-
let exposure;
|
|
136
|
-
try {
|
|
137
|
-
exposure = store.createExposure({
|
|
138
|
-
id,
|
|
139
|
-
piboSessionId,
|
|
140
|
-
projectId: options.project?.trim() || inferredProjectId(session.metadata),
|
|
141
|
-
label: options.name?.trim() || `Preview ${port}`,
|
|
142
|
-
targetHost: target?.host ?? "127.0.0.1",
|
|
143
|
-
targetPort: port,
|
|
144
|
-
targetProcessId: targetProcess?.pid,
|
|
145
|
-
targetProcessStartTicks: targetProcess?.startTicks,
|
|
146
|
-
workspace: resolve(options.workspace ?? session.workspace ?? process.cwd()),
|
|
147
|
-
managementMode: command ? "managed" : "external",
|
|
148
|
-
startCommand: command,
|
|
149
|
-
serverState: command ? "stopped" : undefined,
|
|
150
|
-
createdAt: now.toISOString(),
|
|
151
|
-
expiresAt: new Date(now.getTime() + options.ttlMinutes * 60_000).toISOString(),
|
|
152
|
-
});
|
|
153
|
-
if (command)
|
|
154
|
-
exposure = await startManagedPreview(store, id);
|
|
155
|
-
}
|
|
156
|
-
finally {
|
|
157
|
-
store.close();
|
|
158
|
-
}
|
|
159
|
-
const result = { ...await exposureView(exposure), publicUrl: previewPublicURL(id, baseURL).toString() };
|
|
160
|
-
if (options.json)
|
|
161
|
-
printJson(result);
|
|
162
|
-
else {
|
|
163
|
-
console.log(`${result.id}\t${result.health}\t${result.label}`);
|
|
164
|
-
console.log(`url\t${result.publicUrl}`);
|
|
165
|
-
console.log(`session\t${result.piboSessionId}`);
|
|
166
|
-
console.log(`managed\t${result.managed}`);
|
|
167
|
-
if (result.serverStopAt)
|
|
168
|
-
console.log(`autoStop\t${result.serverStopAt}`);
|
|
169
|
-
console.log(`expires\t${result.expiresAt}`);
|
|
170
|
-
}
|
|
214
|
+
printCreatedPreview(await createPreviewExposure(port, options), options.json);
|
|
215
|
+
});
|
|
216
|
+
program
|
|
217
|
+
.command("expose-worker")
|
|
218
|
+
.argument("<worker>", "Running Pibo compute worker name or id")
|
|
219
|
+
.requiredOption("--session <pibo-session-id>", "Pibo Session that owns the preview")
|
|
220
|
+
.option("--name <label>", "Preview label")
|
|
221
|
+
.option("--workspace <path>", "Workspace recorded for diagnostics")
|
|
222
|
+
.option("--ttl-minutes <minutes>", "Automatic preview-definition lifetime", parsePreviewTtlMinutes, DEFAULT_PREVIEW_TTL_MINUTES)
|
|
223
|
+
.option("--json", "Print JSON")
|
|
224
|
+
.action(async (workerSelector, options) => {
|
|
225
|
+
const worker = await resolvePreviewComputeWorkerTarget(workerSelector);
|
|
226
|
+
const result = await createPreviewExposure(worker.webPort, options, {
|
|
227
|
+
label: worker.name,
|
|
228
|
+
workspace: worker.worktreePath,
|
|
229
|
+
proxyMode: "pibo-compute-dev-auth",
|
|
230
|
+
});
|
|
231
|
+
printCreatedPreview(result, options.json);
|
|
171
232
|
});
|
|
172
233
|
program
|
|
173
234
|
.command("list")
|
|
@@ -258,9 +319,12 @@ export async function runPreviewCli(argv = process.argv) {
|
|
|
258
319
|
program
|
|
259
320
|
.command("doctor")
|
|
260
321
|
.argument("[preview-id]")
|
|
322
|
+
.option("--public", "Verify public DNS, trusted TLS, and Preview-host routing")
|
|
261
323
|
.option("--json", "Print JSON")
|
|
262
324
|
.action(async (id, options) => {
|
|
263
325
|
const baseURL = requirePreviewBaseURL();
|
|
326
|
+
if (options.public && !id)
|
|
327
|
+
throw new Error("--public requires a preview id. Create an active Preview, then run `pibo preview doctor <preview-id> --public`.");
|
|
264
328
|
if (!id) {
|
|
265
329
|
const config = loadPreviewConfig();
|
|
266
330
|
const serverLimits = loadEffectivePreviewServerSettings();
|
|
@@ -277,6 +341,7 @@ export async function runPreviewCli(argv = process.argv) {
|
|
|
277
341
|
const result = {
|
|
278
342
|
configured: true,
|
|
279
343
|
baseURL: baseURL.toString(),
|
|
344
|
+
productionSetup: createPreviewProductionSetupPlan({ baseURL: baseURL.toString() }),
|
|
280
345
|
limits: {
|
|
281
346
|
...serverLimits,
|
|
282
347
|
maxProxyConnections: config.maxProxyConnections ?? DEFAULT_MAX_PREVIEW_PROXY_CONNECTIONS,
|
|
@@ -292,6 +357,8 @@ export async function runPreviewCli(argv = process.argv) {
|
|
|
292
357
|
console.log(`baseURL\t${result.baseURL}`);
|
|
293
358
|
console.log(`active\t${diagnostics.activeExposures}`);
|
|
294
359
|
console.log(`managed\t${diagnostics.managedStartingOrRunning}`);
|
|
360
|
+
console.log(`DNS required\t${result.productionSetup.dnsRecord.name}`);
|
|
361
|
+
console.log(`production guide\tpibo preview setup --base-url ${baseURL.origin}`);
|
|
295
362
|
}
|
|
296
363
|
return;
|
|
297
364
|
}
|
|
@@ -304,15 +371,23 @@ export async function runPreviewCli(argv = process.argv) {
|
|
|
304
371
|
finally {
|
|
305
372
|
store.close();
|
|
306
373
|
}
|
|
307
|
-
const
|
|
374
|
+
const publicChecks = options.public ? await inspectPreviewPublicRoute(baseURL, id) : undefined;
|
|
375
|
+
const result = {
|
|
376
|
+
...await exposureView(exposure),
|
|
377
|
+
...(publicChecks ? { publicChecks } : {}),
|
|
378
|
+
};
|
|
308
379
|
if (options.json)
|
|
309
380
|
printJson(result);
|
|
310
381
|
else {
|
|
311
382
|
console.log(`${result.id}\t${result.health}`);
|
|
312
383
|
console.log(`target\t${result.targetHost}:${result.targetPort}`);
|
|
313
384
|
console.log(`url\t${result.publicUrl}`);
|
|
385
|
+
if (publicChecks) {
|
|
386
|
+
console.log(`DNS\t${publicChecks.dns.status}\t${publicChecks.dns.detail}`);
|
|
387
|
+
console.log(`TLS and routing\t${publicChecks.tlsAndRouting.status}\t${publicChecks.tlsAndRouting.detail}`);
|
|
388
|
+
}
|
|
314
389
|
}
|
|
315
|
-
if (result.health !== "online")
|
|
390
|
+
if (result.health !== "online" || publicChecks && (publicChecks.dns.status !== "ok" || publicChecks.tlsAndRouting.status !== "ok"))
|
|
316
391
|
process.exitCode = 1;
|
|
317
392
|
});
|
|
318
393
|
const removeAction = async (id, options) => {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { listWorkers } from "../compute/docker.js";
|
|
2
|
+
import { validatePreviewPort } from "./network.js";
|
|
3
|
+
export function selectPreviewComputeWorkerTarget(workers, selector) {
|
|
4
|
+
const normalized = selector.trim();
|
|
5
|
+
if (!normalized)
|
|
6
|
+
throw new Error("Compute worker name or id is required");
|
|
7
|
+
const worker = workers.find((candidate) => candidate.name === normalized || candidate.id === normalized);
|
|
8
|
+
if (!worker)
|
|
9
|
+
throw new Error(`Pibo compute worker "${normalized}" was not found`);
|
|
10
|
+
if (worker.role !== "worker" && worker.role !== "dev")
|
|
11
|
+
throw new Error(`Pibo compute target "${worker.name}" is not a managed worker`);
|
|
12
|
+
if (worker.state !== "running")
|
|
13
|
+
throw new Error(`Pibo compute worker "${worker.name}" is not running`);
|
|
14
|
+
const webPort = Number(worker.portMap.web);
|
|
15
|
+
if (!Number.isInteger(webPort))
|
|
16
|
+
throw new Error(`Pibo compute worker "${worker.name}" does not publish a labeled Web port`);
|
|
17
|
+
const bindings = worker.portMap["4788/tcp"]?.split(",") ?? [];
|
|
18
|
+
if (!bindings.includes(`127.0.0.1:${webPort}`)) {
|
|
19
|
+
throw new Error(`Pibo compute worker "${worker.name}" Web port is not published on host loopback`);
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
id: worker.id,
|
|
23
|
+
name: worker.name,
|
|
24
|
+
webPort: validatePreviewPort(webPort),
|
|
25
|
+
worktreePath: worker.worktreePath,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export async function resolvePreviewComputeWorkerTarget(selector) {
|
|
29
|
+
let workers;
|
|
30
|
+
try {
|
|
31
|
+
workers = await listWorkers({ all: true });
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
throw new Error(`Unable to inspect Pibo compute workers: ${error instanceof Error ? error.message : String(error)}`);
|
|
35
|
+
}
|
|
36
|
+
return selectPreviewComputeWorkerTarget(workers, selector);
|
|
37
|
+
}
|
package/dist/previews/config.js
CHANGED
|
@@ -5,6 +5,7 @@ import { parsePreviewBaseURL } from "./base-url.js";
|
|
|
5
5
|
export const DEFAULT_PREVIEW_TTL_MINUTES = 8 * 60;
|
|
6
6
|
export const DEFAULT_PREVIEW_TICKET_TTL_SECONDS = 60;
|
|
7
7
|
export const DEFAULT_PREVIEW_SESSION_TTL_MINUTES = 8 * 60;
|
|
8
|
+
export const PREVIEW_TLS_AUTHORIZATION_PATH = "/api/previews/tls-authorize";
|
|
8
9
|
export function loadPreviewConfig() {
|
|
9
10
|
return loadPiboConfig().preview ?? {};
|
|
10
11
|
}
|
|
@@ -18,7 +19,7 @@ export function loadEffectivePreviewServerSettings() {
|
|
|
18
19
|
}
|
|
19
20
|
export function requirePreviewBaseURL(value = loadPreviewConfig().baseURL) {
|
|
20
21
|
if (!value)
|
|
21
|
-
throw new Error("preview.baseURL is required.
|
|
22
|
+
throw new Error("preview.baseURL is required. Run `pibo preview setup --base-url https://preview.example.com` for DNS, TLS, proxy, and restart instructions.");
|
|
22
23
|
return parsePreviewBaseURL(value);
|
|
23
24
|
}
|
|
24
25
|
export function previewPublicURL(previewId, baseURL = requirePreviewBaseURL()) {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** One-time v4 upgrade: session identity already owns every exposure and authorization. */
|
|
2
|
+
export function migratePreviewSessionOwnership(db) {
|
|
3
|
+
const columns = db.prepare("PRAGMA table_info(preview_exposures)").all();
|
|
4
|
+
if (columns.some((column) => column.name === "project_id")) {
|
|
5
|
+
db.exec("ALTER TABLE preview_exposures DROP COLUMN project_id");
|
|
6
|
+
}
|
|
7
|
+
}
|
package/dist/previews/proxy.js
CHANGED
|
@@ -154,8 +154,10 @@ function requestHeaders(incoming, exposure, requestURL, websocket) {
|
|
|
154
154
|
}
|
|
155
155
|
const targetHost = exposure.targetHost === "::1" ? `[::1]` : exposure.targetHost;
|
|
156
156
|
headers.host = `${targetHost}:${exposure.targetPort}`;
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
if (exposure.proxyMode !== "pibo-compute-dev-auth") {
|
|
158
|
+
headers["x-forwarded-host"] = requestURL.host;
|
|
159
|
+
headers["x-forwarded-proto"] = requestURL.protocol.slice(0, -1);
|
|
160
|
+
}
|
|
159
161
|
if (websocket) {
|
|
160
162
|
headers.connection = "Upgrade";
|
|
161
163
|
headers.upgrade = incoming.upgrade ?? "websocket";
|