mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 05:11:49 +01:00
Merge remote-tracking branch 'public-gh/master' into PAP-989-multi-user-implementation-using-plan-from-pap-958
* public-gh/master: (32 commits) fix(dev-runner): tighten worktree env bootstrap fix(inbox): avoid refetching on filter-only changes fix(codex-local): avoid fast mode in env probe fix: isolate dev runner worktree env Broaden comment matches in issue search Add inbox issue search fallback feat(codex-local): add fast mode support Harden tailnet bind setup Fix dev runner workspace import regression Introduce bind presets for deployment setup fix: address PR 3355 review regressions test(ui): fix heartbeat run fixture drift fix: restore inbox optimistic run fixture fix: keep thread polish independent of quicklook routing fix: keep runtime UI changes self-contained fix: keep inbox quicklook and tests standalone fix: use CLI tsx entrypoint for workspace preflight chore: improve worktree tooling and security docs feat: polish issue thread markdown and references fix: harden heartbeat and adapter runtime workflows ... # Conflicts: # cli/src/__tests__/worktree.test.ts # scripts/ensure-workspace-package-links.ts # server/src/__tests__/claude-local-execute.test.ts # server/src/__tests__/issues-service.test.ts # ui/src/components/Layout.tsx
This commit is contained in:
commit
e6fd9d29db
219 files changed
+24351
-2690
No files matched your search
+78
-8
@@ -6,6 +6,7 @@ import { createInterface } from "node:readline/promises";
|
||||
import { stdin, stdout } from "node:process";
|
||||
import { shouldTrackDevServerPath } from "./dev-runner-paths.mjs";
|
||||
import { createDevServiceIdentity, repoRoot } from "./dev-service-profile.ts";
|
||||
import { bootstrapDevRunnerWorktreeEnv } from "../server/src/dev-runner-worktree.ts";
|
||||
import {
|
||||
findAdoptableLocalService,
|
||||
removeLocalServiceRegistryRecord,
|
||||
@@ -13,6 +14,19 @@ import {
|
||||
writeLocalServiceRegistryRecord,
|
||||
} from "../server/src/services/local-service-supervisor.ts";
|
||||
|
||||
// Keep these values local so the dev runner can boot from the server package's
|
||||
// tsx context without requiring workspace package resolution first.
|
||||
const BIND_MODES = ["loopback", "lan", "tailnet", "custom"] as const;
|
||||
type BindMode = (typeof BIND_MODES)[number];
|
||||
|
||||
const worktreeEnvBootstrap = bootstrapDevRunnerWorktreeEnv(repoRoot, process.env);
|
||||
if (worktreeEnvBootstrap.missingEnv) {
|
||||
console.error(
|
||||
`[paperclip] linked git worktree at ${repoRoot} is missing ${path.relative(repoRoot, worktreeEnvBootstrap.envPath)}. Run \`paperclipai worktree init\` in this worktree before \`pnpm dev\`.`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const mode = process.argv[2] === "watch" ? "watch" : "dev";
|
||||
const cliArgs = process.argv.slice(3);
|
||||
const scanIntervalMs = 1500;
|
||||
@@ -61,13 +75,36 @@ const tailscaleAuthFlagNames = new Set([
|
||||
]);
|
||||
|
||||
let tailscaleAuth = false;
|
||||
let bindMode: BindMode | null = null;
|
||||
let bindHost: string | null = null;
|
||||
const forwardedArgs: string[] = [];
|
||||
|
||||
for (const arg of cliArgs) {
|
||||
for (let index = 0; index < cliArgs.length; index += 1) {
|
||||
const arg = cliArgs[index];
|
||||
if (tailscaleAuthFlagNames.has(arg)) {
|
||||
tailscaleAuth = true;
|
||||
continue;
|
||||
}
|
||||
if (arg === "--bind") {
|
||||
const value = cliArgs[index + 1];
|
||||
if (!value || value.startsWith("--") || !BIND_MODES.includes(value as BindMode)) {
|
||||
console.error(`[paperclip] invalid --bind value. Use one of: ${BIND_MODES.join(", ")}`);
|
||||
process.exit(1);
|
||||
}
|
||||
bindMode = value as BindMode;
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if (arg === "--bind-host") {
|
||||
const value = cliArgs[index + 1];
|
||||
if (!value || value.startsWith("--")) {
|
||||
console.error("[paperclip] --bind-host requires a value");
|
||||
process.exit(1);
|
||||
}
|
||||
bindHost = value;
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
forwardedArgs.push(arg);
|
||||
}
|
||||
|
||||
@@ -77,6 +114,16 @@ if (process.env.npm_config_tailscale_auth === "true") {
|
||||
if (process.env.npm_config_authenticated_private === "true") {
|
||||
tailscaleAuth = true;
|
||||
}
|
||||
if (!bindMode && process.env.npm_config_bind && BIND_MODES.includes(process.env.npm_config_bind as BindMode)) {
|
||||
bindMode = process.env.npm_config_bind as BindMode;
|
||||
}
|
||||
if (!bindHost && process.env.npm_config_bind_host) {
|
||||
bindHost = process.env.npm_config_bind_host;
|
||||
}
|
||||
if (bindMode === "custom" && !bindHost) {
|
||||
console.error("[paperclip] --bind custom requires --bind-host <host>");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const env: NodeJS.ProcessEnv = {
|
||||
...process.env,
|
||||
@@ -93,13 +140,36 @@ if (mode === "watch") {
|
||||
env.PAPERCLIP_MIGRATION_AUTO_APPLY ??= "true";
|
||||
}
|
||||
|
||||
if (tailscaleAuth) {
|
||||
env.PAPERCLIP_DEPLOYMENT_MODE = "authenticated";
|
||||
env.PAPERCLIP_DEPLOYMENT_EXPOSURE = "private";
|
||||
env.PAPERCLIP_AUTH_BASE_URL_MODE = "auto";
|
||||
env.HOST = "0.0.0.0";
|
||||
console.log("[paperclip] dev mode: authenticated/private (tailscale-friendly) on 0.0.0.0");
|
||||
if (tailscaleAuth || bindMode) {
|
||||
const effectiveBind = bindMode ?? "lan";
|
||||
if (tailscaleAuth) {
|
||||
console.log("[paperclip] note: --tailscale-auth/--authenticated-private are legacy aliases for --bind lan");
|
||||
}
|
||||
env.PAPERCLIP_BIND = effectiveBind;
|
||||
if (bindHost) {
|
||||
env.PAPERCLIP_BIND_HOST = bindHost;
|
||||
} else {
|
||||
delete env.PAPERCLIP_BIND_HOST;
|
||||
}
|
||||
if (effectiveBind === "loopback" && !tailscaleAuth) {
|
||||
delete env.PAPERCLIP_DEPLOYMENT_MODE;
|
||||
delete env.PAPERCLIP_DEPLOYMENT_EXPOSURE;
|
||||
delete env.PAPERCLIP_AUTH_BASE_URL_MODE;
|
||||
console.log("[paperclip] dev mode: local_trusted (bind=loopback)");
|
||||
} else {
|
||||
env.PAPERCLIP_DEPLOYMENT_MODE = "authenticated";
|
||||
env.PAPERCLIP_DEPLOYMENT_EXPOSURE = "private";
|
||||
env.PAPERCLIP_AUTH_BASE_URL_MODE = "auto";
|
||||
console.log(
|
||||
`[paperclip] dev mode: authenticated/private (bind=${effectiveBind}${bindHost ? `:${bindHost}` : ""})`,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
delete env.PAPERCLIP_BIND;
|
||||
delete env.PAPERCLIP_BIND_HOST;
|
||||
delete env.PAPERCLIP_DEPLOYMENT_MODE;
|
||||
delete env.PAPERCLIP_DEPLOYMENT_EXPOSURE;
|
||||
delete env.PAPERCLIP_AUTH_BASE_URL_MODE;
|
||||
console.log("[paperclip] dev mode: local_trusted (default)");
|
||||
}
|
||||
|
||||
@@ -107,7 +177,7 @@ const serverPort = Number.parseInt(env.PORT ?? process.env.PORT ?? "3100", 10) |
|
||||
const devService = createDevServiceIdentity({
|
||||
mode,
|
||||
forwardedArgs,
|
||||
tailscaleAuth,
|
||||
networkProfile: tailscaleAuth ? `legacy:${bindMode ?? "lan"}` : (bindMode ?? "default"),
|
||||
port: serverPort,
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user