@codions/portta 0.0.0-develop.171.sha-d749180 → 0.0.0-develop.174.sha-9f22fb0
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/assets/skills/portta-workflows/SKILL.md +1 -1
- package/dist/assets/workflows/bake-off.workflow.js +6 -5
- package/dist/assets/workflows/code-review.workflow.js +4 -4
- package/dist/assets/workflows/deep-research.workflow.js +4 -3
- package/dist/assets/workflows/multi-provider-review.workflow.js +5 -4
- package/dist/assets/workflows/provider-debate.workflow.js +7 -6
- package/dist/assets/workflows/second-opinion.workflow.js +4 -3
- package/dist/cli.js +794 -847
- package/dist/documentation.json +1 -1
- package/dist/host.js +53 -93
- package/dist/runtime/.env.example +8 -17
- package/dist/runtime/VERSION +1 -1
- package/dist/runtime/docker/compose/features/panel-host.yaml +4 -5
- package/dist/runtime/templates/README.md +9 -6
- package/dist/runtime/templates/overlays/07-worktree.env +1 -1
- package/dist/runtime/templates/project/PORTTA.md +3 -3
- package/dist/supervisor.js +0 -1
- package/package.json +2 -5
- package/dist/runtime/config/traefik/dynamic/auth.example.yaml.disabled +0 -24
- package/dist/runtime/docker/images/README.md +0 -12
- package/dist/runtime/docker/images/sandbox/Dockerfile +0 -79
- package/dist/runtime/docker/images/sandbox/README.md +0 -109
- package/dist/runtime/docker/images/sandbox/VERSION +0 -1
- package/dist/runtime/docker/images/sandbox/agents/claude-code.sh +0 -18
- package/dist/runtime/docker/images/sandbox/agents/codex.sh +0 -4
- package/dist/runtime/docker/images/sandbox/agents/opencode.sh +0 -4
- package/dist/runtime/docker/images/sandbox/agents/pi.sh +0 -4
- package/dist/runtime/docker/images/sandbox/scripts/entrypoint.sh +0 -8
- package/dist/runtime/docker/images/sandbox/scripts/generate-manifest.mjs +0 -81
- package/dist/runtime/docker/images/sandbox/scripts/install-tools.sh +0 -46
- package/dist/runtime/docker/images/sandbox/scripts/verify-image.sh +0 -18
package/dist/host.js
CHANGED
|
@@ -40819,7 +40819,6 @@ var RUNTIME_IDENTITY = {
|
|
|
40819
40819
|
tmuxBufferPrefix: `${APP_SLUG}-prompt`,
|
|
40820
40820
|
dockerContainerPrefix: APP_SLUG,
|
|
40821
40821
|
tempUploadDir: `${APP_SLUG}-uploads`,
|
|
40822
|
-
dockerImage: "portta-sandbox",
|
|
40823
40822
|
gitBaseConfigKey: `${APP_SLUG}.base`
|
|
40824
40823
|
};
|
|
40825
40824
|
var LINEAR_IDENTITY = {
|
|
@@ -40929,41 +40928,11 @@ import { readFileSync as readFileSync2 } from "node:fs";
|
|
|
40929
40928
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
40930
40929
|
import { dirname as dirname2, resolve } from "node:path";
|
|
40931
40930
|
var import_yaml = __toESM(require_dist(), 1);
|
|
40932
|
-
|
|
40933
|
-
// ../host/src/modules/taskflow/lib/log.ts
|
|
40934
|
-
var DEBUG = process.env[ENV_NAMES.debug] === "1";
|
|
40935
|
-
function ts() {
|
|
40936
|
-
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
40937
|
-
}
|
|
40938
|
-
function redactSecrets(text) {
|
|
40939
|
-
return text.replace(/Bearer\s+\S+/gi, "Bearer [REDACTED]").replace(new RegExp(`(${ENV_NAMES.controlToken}=)\\S+`, "gi"), "$1[REDACTED]");
|
|
40940
|
-
}
|
|
40941
|
-
function safe(msg) {
|
|
40942
|
-
return redactSecrets(msg);
|
|
40943
|
-
}
|
|
40944
|
-
var log = {
|
|
40945
|
-
info(msg) {
|
|
40946
|
-
console.log(`[${ts()}] ${safe(msg)}`);
|
|
40947
|
-
},
|
|
40948
|
-
debug(msg) {
|
|
40949
|
-
if (DEBUG) console.log(`[${ts()}] ${safe(msg)}`);
|
|
40950
|
-
},
|
|
40951
|
-
warn(msg) {
|
|
40952
|
-
console.warn(`[${ts()}] ${safe(msg)}`);
|
|
40953
|
-
},
|
|
40954
|
-
error(msg, err2) {
|
|
40955
|
-
const redacted = safe(msg);
|
|
40956
|
-
err2 !== void 0 ? console.error(`[${ts()}] ${redacted}`, err2) : console.error(`[${ts()}] ${redacted}`);
|
|
40957
|
-
}
|
|
40958
|
-
};
|
|
40959
|
-
|
|
40960
|
-
// ../host/src/modules/taskflow/adapters/config.ts
|
|
40961
40931
|
function parseWorktreeRoot(raw2, fallback) {
|
|
40962
40932
|
if (!isRecord(raw2)) return fallback;
|
|
40963
40933
|
if (isRecord(raw2.worktrees) && typeof raw2.worktrees.root === "string" && raw2.worktrees.root.trim()) {
|
|
40964
40934
|
return raw2.worktrees.root.trim();
|
|
40965
40935
|
}
|
|
40966
|
-
if (typeof raw2.worktreeRoot === "string" && raw2.worktreeRoot.trim()) return raw2.worktreeRoot.trim();
|
|
40967
40936
|
return fallback;
|
|
40968
40937
|
}
|
|
40969
40938
|
function parseExposure(raw2) {
|
|
@@ -41108,18 +41077,15 @@ function parseProfile(raw2, fallbackRuntime) {
|
|
|
41108
41077
|
...typeof raw2.environment.cwd === "string" && raw2.environment.cwd.trim() ? { cwd: raw2.environment.cwd.trim() } : {},
|
|
41109
41078
|
...typeof raw2.environment.stopCommand === "string" && raw2.environment.stopCommand.trim() ? { stopCommand: raw2.environment.stopCommand.trim() } : {}
|
|
41110
41079
|
} : void 0;
|
|
41111
|
-
const legacyRuntimePane = environment && (environment.provider === "host" || environment.provider === "auto") && !environment.command ? panes.find((pane) => pane.id === "app" && pane.kind === "command" && Boolean(pane.command)) : void 0;
|
|
41112
|
-
const effectiveEnvironment = legacyRuntimePane ? { ...environment, command: legacyRuntimePane.command } : environment;
|
|
41113
|
-
const effectivePanes = legacyRuntimePane ? panes.filter((pane) => pane !== legacyRuntimePane) : panes;
|
|
41114
41080
|
return {
|
|
41115
41081
|
runtime,
|
|
41116
41082
|
envPassthrough,
|
|
41117
41083
|
...raw2.yolo === true ? { yolo: true } : {},
|
|
41118
|
-
panes
|
|
41084
|
+
panes,
|
|
41119
41085
|
...typeof raw2.systemPrompt === "string" && raw2.systemPrompt.length > 0 ? { systemPrompt: raw2.systemPrompt } : {},
|
|
41120
41086
|
...image ? { image } : {},
|
|
41121
41087
|
...mounts ? { mounts } : {},
|
|
41122
|
-
...
|
|
41088
|
+
...environment && Object.keys(environment).length > 0 ? { environment } : {}
|
|
41123
41089
|
};
|
|
41124
41090
|
}
|
|
41125
41091
|
function parseProfiles(raw2, includeDefaultProfile) {
|
|
@@ -41278,17 +41244,10 @@ function parseTeamKeyList(raw2) {
|
|
|
41278
41244
|
const keys = raw2.filter((entry) => typeof entry === "string").map((entry) => entry.trim().toUpperCase()).filter((entry) => entry.length > 0);
|
|
41279
41245
|
return keys.length > 0 ? Array.from(new Set(keys)) : void 0;
|
|
41280
41246
|
}
|
|
41281
|
-
var warnedLegacyLinearTeamId = false;
|
|
41282
41247
|
function parseLinearIntegration(parsed) {
|
|
41283
41248
|
const defaults = DEFAULT_CONFIG.integrations.linear;
|
|
41284
41249
|
const linear = isRecord(parsed.integrations) && isRecord(parsed.integrations.linear) ? parsed.integrations.linear : null;
|
|
41285
41250
|
if (!linear) return { ...defaults };
|
|
41286
|
-
if (typeof linear.teamId === "string" && !warnedLegacyLinearTeamId) {
|
|
41287
|
-
warnedLegacyLinearTeamId = true;
|
|
41288
|
-
log.warn(
|
|
41289
|
-
"[config] integrations.linear.teamId is no longer used \u2014 the ticket team is now picked at creation time in the dashboard"
|
|
41290
|
-
);
|
|
41291
|
-
}
|
|
41292
41251
|
const watchTeams = parseTeamKeyList(linear.watchTeams);
|
|
41293
41252
|
return {
|
|
41294
41253
|
enabled: typeof linear.enabled === "boolean" ? linear.enabled : defaults.enabled,
|
|
@@ -48005,6 +47964,35 @@ exec ${JSON.stringify(executable)} "$@"
|
|
|
48005
47964
|
// ../host/src/modules/taskflow/adapters/projects-registry.ts
|
|
48006
47965
|
import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
48007
47966
|
import { dirname as dirname6 } from "node:path";
|
|
47967
|
+
|
|
47968
|
+
// ../host/src/modules/taskflow/lib/log.ts
|
|
47969
|
+
var DEBUG = process.env[ENV_NAMES.debug] === "1";
|
|
47970
|
+
function ts() {
|
|
47971
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
47972
|
+
}
|
|
47973
|
+
function redactSecrets(text) {
|
|
47974
|
+
return text.replace(/Bearer\s+\S+/gi, "Bearer [REDACTED]").replace(new RegExp(`(${ENV_NAMES.controlToken}=)\\S+`, "gi"), "$1[REDACTED]");
|
|
47975
|
+
}
|
|
47976
|
+
function safe(msg) {
|
|
47977
|
+
return redactSecrets(msg);
|
|
47978
|
+
}
|
|
47979
|
+
var log = {
|
|
47980
|
+
info(msg) {
|
|
47981
|
+
console.log(`[${ts()}] ${safe(msg)}`);
|
|
47982
|
+
},
|
|
47983
|
+
debug(msg) {
|
|
47984
|
+
if (DEBUG) console.log(`[${ts()}] ${safe(msg)}`);
|
|
47985
|
+
},
|
|
47986
|
+
warn(msg) {
|
|
47987
|
+
console.warn(`[${ts()}] ${safe(msg)}`);
|
|
47988
|
+
},
|
|
47989
|
+
error(msg, err2) {
|
|
47990
|
+
const redacted = safe(msg);
|
|
47991
|
+
err2 !== void 0 ? console.error(`[${ts()}] ${redacted}`, err2) : console.error(`[${ts()}] ${redacted}`);
|
|
47992
|
+
}
|
|
47993
|
+
};
|
|
47994
|
+
|
|
47995
|
+
// ../host/src/modules/taskflow/adapters/projects-registry.ts
|
|
48008
47996
|
function defaultRegistryFile() {
|
|
48009
47997
|
return globalPaths().projectsRegistry;
|
|
48010
47998
|
}
|
|
@@ -50900,25 +50888,21 @@ function isRecord5(raw2) {
|
|
|
50900
50888
|
function normalizeConversationMeta(raw2) {
|
|
50901
50889
|
if (!raw2) return raw2;
|
|
50902
50890
|
if (raw2.provider === "codexAppServer") {
|
|
50903
|
-
|
|
50904
|
-
const threadId = raw2.threadId || raw2.conversationId;
|
|
50905
|
-
if (!conversationId2 || !threadId) return void 0;
|
|
50891
|
+
if (!raw2.conversationId || !raw2.threadId) return void 0;
|
|
50906
50892
|
const normalized2 = {
|
|
50907
50893
|
provider: "codexAppServer",
|
|
50908
|
-
conversationId:
|
|
50909
|
-
threadId,
|
|
50894
|
+
conversationId: raw2.conversationId,
|
|
50895
|
+
threadId: raw2.threadId,
|
|
50910
50896
|
cwd: raw2.cwd,
|
|
50911
50897
|
lastSeenAt: raw2.lastSeenAt
|
|
50912
50898
|
};
|
|
50913
50899
|
return normalized2;
|
|
50914
50900
|
}
|
|
50915
|
-
|
|
50916
|
-
const sessionId = raw2.sessionId || raw2.conversationId;
|
|
50917
|
-
if (!conversationId || !sessionId) return void 0;
|
|
50901
|
+
if (!raw2.conversationId || !raw2.sessionId) return void 0;
|
|
50918
50902
|
const normalized = {
|
|
50919
50903
|
provider: "claudeCode",
|
|
50920
|
-
conversationId,
|
|
50921
|
-
sessionId,
|
|
50904
|
+
conversationId: raw2.conversationId,
|
|
50905
|
+
sessionId: raw2.sessionId,
|
|
50922
50906
|
cwd: raw2.cwd,
|
|
50923
50907
|
lastSeenAt: raw2.lastSeenAt
|
|
50924
50908
|
};
|
|
@@ -53336,10 +53320,7 @@ ${oneshotPrompt}` : oneshotPrompt ?? baseSystemPrompt;
|
|
|
53336
53320
|
return panes.length > 0 ? panes : [{ id: "runtime", kind: "runtime", cwd: "worktree" }];
|
|
53337
53321
|
}
|
|
53338
53322
|
if (panes.some((pane) => pane.kind === "runtime")) return panes;
|
|
53339
|
-
|
|
53340
|
-
const runtimePane = { id: "runtime", kind: "runtime", split: "right", sizePct: 30, cwd: "worktree" };
|
|
53341
|
-
if (legacyShell >= 0) panes.splice(legacyShell, 1, runtimePane);
|
|
53342
|
-
else panes.push(runtimePane);
|
|
53323
|
+
panes.push({ id: "runtime", kind: "runtime", split: "right", sizePct: 30, cwd: "worktree" });
|
|
53343
53324
|
return panes;
|
|
53344
53325
|
}
|
|
53345
53326
|
requireDockerProfile(profile) {
|
|
@@ -60041,10 +60022,15 @@ var migrations = [
|
|
|
60041
60022
|
input_json TEXT NOT NULL,
|
|
60042
60023
|
status TEXT NOT NULL CHECK(status IN ('queued', 'provisioning', 'running', 'waiting_input', 'completed', 'failed', 'cancelled', 'interrupted')),
|
|
60043
60024
|
workspace_policy TEXT NOT NULL CHECK(workspace_policy IN ('none', 'run')),
|
|
60025
|
+
workspace_strategy TEXT CHECK(workspace_strategy IN ('isolated_worktree', 'new_branch', 'current_branch')),
|
|
60026
|
+
workspace_access TEXT CHECK(workspace_access IN ('shared_read', 'exclusive_write')),
|
|
60044
60027
|
workflow_snapshot_id TEXT,
|
|
60045
60028
|
workspace_id TEXT,
|
|
60046
60029
|
worktree_path TEXT,
|
|
60047
60030
|
canonical_workspace_path TEXT,
|
|
60031
|
+
checkout_canonical_path TEXT,
|
|
60032
|
+
checkout_branch TEXT,
|
|
60033
|
+
environment_id TEXT,
|
|
60048
60034
|
branch TEXT,
|
|
60049
60035
|
base_branch TEXT,
|
|
60050
60036
|
base_commit TEXT,
|
|
@@ -60072,6 +60058,7 @@ var migrations = [
|
|
|
60072
60058
|
path TEXT NOT NULL,
|
|
60073
60059
|
content_hash TEXT NOT NULL,
|
|
60074
60060
|
engine_version TEXT NOT NULL,
|
|
60061
|
+
key_version TEXT NOT NULL DEFAULT 'v1',
|
|
60075
60062
|
source TEXT NOT NULL,
|
|
60076
60063
|
metadata_json TEXT NOT NULL,
|
|
60077
60064
|
created_at TEXT NOT NULL
|
|
@@ -60096,6 +60083,7 @@ var migrations = [
|
|
|
60096
60083
|
error TEXT,
|
|
60097
60084
|
session_id TEXT,
|
|
60098
60085
|
capabilities_json TEXT,
|
|
60086
|
+
checkpoint_json TEXT,
|
|
60099
60087
|
started_at TEXT,
|
|
60100
60088
|
completed_at TEXT,
|
|
60101
60089
|
UNIQUE(run_id, node_key, attempt)
|
|
@@ -60107,10 +60095,7 @@ var migrations = [
|
|
|
60107
60095
|
source TEXT NOT NULL,
|
|
60108
60096
|
updated_at TEXT NOT NULL
|
|
60109
60097
|
);
|
|
60110
|
-
|
|
60111
|
-
"ALTER TABLE executions ADD COLUMN checkpoint_json TEXT;",
|
|
60112
|
-
"ALTER TABLE workflow_snapshots ADD COLUMN key_version TEXT NOT NULL DEFAULT 'v1';",
|
|
60113
|
-
`
|
|
60098
|
+
|
|
60114
60099
|
CREATE TABLE IF NOT EXISTS run_events (
|
|
60115
60100
|
id TEXT PRIMARY KEY,
|
|
60116
60101
|
run_id TEXT NOT NULL REFERENCES runs(id),
|
|
@@ -60123,8 +60108,7 @@ var migrations = [
|
|
|
60123
60108
|
payload_json TEXT NOT NULL,
|
|
60124
60109
|
UNIQUE(run_id, sequence)
|
|
60125
60110
|
);
|
|
60126
|
-
|
|
60127
|
-
`
|
|
60111
|
+
|
|
60128
60112
|
CREATE TABLE IF NOT EXISTS workspace_leases (
|
|
60129
60113
|
id TEXT PRIMARY KEY,
|
|
60130
60114
|
run_id TEXT NOT NULL REFERENCES runs(id),
|
|
@@ -60142,12 +60126,7 @@ var migrations = [
|
|
|
60142
60126
|
updated_at TEXT NOT NULL,
|
|
60143
60127
|
released_at TEXT
|
|
60144
60128
|
);
|
|
60145
|
-
|
|
60146
|
-
"ALTER TABLE runs ADD COLUMN workspace_strategy TEXT CHECK(workspace_strategy IN ('isolated_worktree', 'new_branch', 'current_branch'));",
|
|
60147
|
-
"ALTER TABLE runs ADD COLUMN workspace_access TEXT CHECK(workspace_access IN ('shared_read', 'exclusive_write'));",
|
|
60148
|
-
"ALTER TABLE runs ADD COLUMN checkout_canonical_path TEXT;",
|
|
60149
|
-
"ALTER TABLE runs ADD COLUMN checkout_branch TEXT;",
|
|
60150
|
-
`
|
|
60129
|
+
|
|
60151
60130
|
CREATE TABLE IF NOT EXISTS checkout_claims (
|
|
60152
60131
|
run_id TEXT PRIMARY KEY REFERENCES runs(id),
|
|
60153
60132
|
project_id TEXT NOT NULL,
|
|
@@ -60156,8 +60135,7 @@ var migrations = [
|
|
|
60156
60135
|
created_at TEXT NOT NULL
|
|
60157
60136
|
);
|
|
60158
60137
|
CREATE INDEX IF NOT EXISTS checkout_claims_path_idx ON checkout_claims(project_id, canonical_path);
|
|
60159
|
-
|
|
60160
|
-
"ALTER TABLE runs ADD COLUMN environment_id TEXT;"
|
|
60138
|
+
`
|
|
60161
60139
|
];
|
|
60162
60140
|
function defaultRunStorePath() {
|
|
60163
60141
|
return globalPaths().database;
|
|
@@ -70927,7 +70905,7 @@ function createProjectApp(runtime, instancePrefix, host) {
|
|
|
70927
70905
|
const reconciliationService = runtime.reconciliationService;
|
|
70928
70906
|
const codexAppServerClient = new CodexAppServerClient({
|
|
70929
70907
|
clientName: RUNTIME_IDENTITY.codexClientName,
|
|
70930
|
-
clientVersion:
|
|
70908
|
+
clientVersion: PORTTA_FLOW_VERSION
|
|
70931
70909
|
});
|
|
70932
70910
|
const claudeCliClient = new ClaudeCliClient();
|
|
70933
70911
|
const worktreeConversationService = new WorktreeConversationService({
|
|
@@ -72364,8 +72342,8 @@ function createTaskflowHost(options) {
|
|
|
72364
72342
|
manager,
|
|
72365
72343
|
apps,
|
|
72366
72344
|
allowlist: options.projectAllowlist,
|
|
72367
|
-
//
|
|
72368
|
-
//
|
|
72345
|
+
// Backs the project-setup status listing. Registration itself does not
|
|
72346
|
+
// scaffold or launch an agent; `taskflow init` is the authoring path.
|
|
72369
72347
|
initTracker: new ProjectInitTracker(),
|
|
72370
72348
|
closeSockets: (prefix) => sockets.closeProject(prefix)
|
|
72371
72349
|
});
|
|
@@ -72428,7 +72406,7 @@ function createDaemonTaskflowHost(context) {
|
|
|
72428
72406
|
port: hostListen(env2).port,
|
|
72429
72407
|
workflowBuiltinsDir: taskflowAssets(env2).workflowBuiltinsDir,
|
|
72430
72408
|
version: env2.PORTTA_VERSION || "0.0.0-local",
|
|
72431
|
-
buildDate: true ? "2026-09-
|
|
72409
|
+
buildDate: true ? "2026-09-18T02:50:11Z" : (/* @__PURE__ */ new Date()).toISOString(),
|
|
72432
72410
|
environmentStore: createEnvironmentStore(paths.database),
|
|
72433
72411
|
hostEnvironmentProvider: new HostEnvironmentProvider(),
|
|
72434
72412
|
devContainerProvider: new DevContainerProvider(),
|
|
@@ -73666,24 +73644,6 @@ var upgradeWebSocket = defineWebSocketHelper(async (c, events, options) => {
|
|
|
73666
73644
|
// ../core/src/diagnostics.ts
|
|
73667
73645
|
var ENVIRONMENT_COLLECT_INTERVAL_MS = 5 * 60 * 1e3;
|
|
73668
73646
|
|
|
73669
|
-
// ../core/src/endpoints.ts
|
|
73670
|
-
var PROVIDERS = [
|
|
73671
|
-
{ id: "internal", scope: "internal", requires: null, optional: false },
|
|
73672
|
-
{ id: "local", scope: "local", requires: "localhost", optional: false },
|
|
73673
|
-
{ id: "lan", scope: "lan", requires: "lan", optional: true },
|
|
73674
|
-
{ id: "tailscale", scope: "private", requires: "tailscale", optional: true },
|
|
73675
|
-
{ id: "tailscale-serve", scope: "private", requires: "tailscale-https", optional: true },
|
|
73676
|
-
{ id: "public-ip", scope: "public", requires: "public-ipv4", optional: true },
|
|
73677
|
-
{ id: "auto-domain", scope: "public", requires: "auto-domain", optional: true },
|
|
73678
|
-
{ id: "custom-domain", scope: "public", requires: "custom-domain", optional: true },
|
|
73679
|
-
{ id: "cloudflare-tunnel", scope: "public", requires: "cloudflare-tunnel", optional: true },
|
|
73680
|
-
{ id: "bridge", scope: "local", requires: null, optional: true }
|
|
73681
|
-
];
|
|
73682
|
-
var PROVIDERS_BY_ID = new Map(PROVIDERS.map((spec) => [spec.id, spec]));
|
|
73683
|
-
|
|
73684
|
-
// ../core/src/host.ts
|
|
73685
|
-
var MIB = 1024 * 1024;
|
|
73686
|
-
|
|
73687
73647
|
// ../core/src/metrics.ts
|
|
73688
73648
|
var HISTORY_RETENTION_SECONDS = 60 * 60;
|
|
73689
73649
|
var DOCKER_SIZE_UNITS = {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# Portta environment structure: 1
|
|
2
1
|
# ============================================================================
|
|
3
2
|
# Portta: configuration
|
|
4
3
|
# ============================================================================
|
|
@@ -28,7 +27,7 @@ PORTTA_PROJECT_NAME=portta
|
|
|
28
27
|
# Changing it changes the reference; files are not moved.
|
|
29
28
|
# Default: ~/projects (user) or /srv/projects (root). Not PORTTA_HOME.
|
|
30
29
|
PORTTA_PROJECTS_HOME=
|
|
31
|
-
# PORTTA_PROJECTS_HOME
|
|
30
|
+
# PORTTA_PROJECTS_HOME=/srv/projects
|
|
32
31
|
|
|
33
32
|
# Shared external Docker network that consumer projects attach published
|
|
34
33
|
# HTTP services to. Created by `bootstrap`, never removed automatically.
|
|
@@ -57,10 +56,6 @@ PORTTA_ACCESS_LOG=false
|
|
|
57
56
|
# The remote-public profile raises this to `delete` on its own.
|
|
58
57
|
PORTTA_ALIAS_HEADERS_STRATEGY=keep
|
|
59
58
|
|
|
60
|
-
# ----------------------------------------------------------------------------
|
|
61
|
-
# Local profile
|
|
62
|
-
# ----------------------------------------------------------------------------
|
|
63
|
-
|
|
64
59
|
# ----------------------------------------------------------------------------
|
|
65
60
|
# Project domain: what every project hostname is built on
|
|
66
61
|
# ----------------------------------------------------------------------------
|
|
@@ -185,7 +180,7 @@ PORTTA_PANEL_ADVERTISED_HOST=
|
|
|
185
180
|
# access mode turns it on by itself.
|
|
186
181
|
PORTTA_WEB_READ_ONLY=false
|
|
187
182
|
|
|
188
|
-
# The panel's own front door
|
|
183
|
+
# The panel's own front door.
|
|
189
184
|
#
|
|
190
185
|
# disabled every request is the local operator. Legal wherever the set of
|
|
191
186
|
# people who can reach the panel is already an authenticated set:
|
|
@@ -264,19 +259,15 @@ PORTTA_WEB_DEV=false
|
|
|
264
259
|
|
|
265
260
|
# Private, internal network carrying panel -> its own Docker socket proxy.
|
|
266
261
|
PORTTA_WEB_NETWORK=portta-web
|
|
267
|
-
#
|
|
262
|
+
# The host uid:gid the panel and the authentication service run as. .env is
|
|
263
|
+
# owner-only, so the panel has to run as whoever owns it or the Settings page
|
|
264
|
+
# cannot save; the authentication service reads .env once and the owner-only
|
|
265
|
+
# protection store on every request. `setup`, `bootstrap` and `web up` record
|
|
266
|
+
# "$(id -u):$(id -g)" here when it is missing; the image's own `node` is only
|
|
267
|
+
# right when the host uid happens to be 1000.
|
|
268
268
|
PORTTA_WEB_USER=
|
|
269
269
|
PORTTA_AUTH_USER=
|
|
270
|
-
|
|
271
|
-
# User the panel container runs as. .env is owner-only, so the panel has to run
|
|
272
|
-
# as whoever owns it or the Settings page cannot save. `bootstrap`, `web up` and
|
|
273
|
-
# the installer record "$(id -u):$(id -g)" here when it is missing; the image's
|
|
274
|
-
# own `node` is only right when the host uid happens to be 1000.
|
|
275
270
|
# PORTTA_WEB_USER=1000:1000
|
|
276
|
-
|
|
277
|
-
# The user the authentication service runs as. Same reason as above: it reads
|
|
278
|
-
# .env once and the owner-only protection store on every request, and both
|
|
279
|
-
# belong to whoever installed Portta. The installer records the right value.
|
|
280
271
|
# PORTTA_AUTH_USER=1000:1000
|
|
281
272
|
|
|
282
273
|
# ----------------------------------------------------------------------------
|
package/dist/runtime/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.0.0-develop.
|
|
1
|
+
0.0.0-develop.174.sha-9f22fb0
|
|
@@ -9,11 +9,10 @@
|
|
|
9
9
|
# WebSocket through its authorised proxy
|
|
10
10
|
# (docs/development/adr/0047-host-daemon-and-panel-proxy.md).
|
|
11
11
|
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
# its own routes.
|
|
12
|
+
# Issues are the panel's work surface and are read through the daemon
|
|
13
|
+
# (docs/development/adr/0018-github-issues-through-the-gh-cli.md), so the
|
|
14
|
+
# connection is part of having a panel. PORTTA_TASKFLOW only switches Task
|
|
15
|
+
# Flow's own routes on; it does not decide whether this overlay applies.
|
|
17
16
|
#
|
|
18
17
|
# What this adds to the panel, and nothing else
|
|
19
18
|
# ----------------------------------------------
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
# Templates
|
|
2
2
|
|
|
3
|
-
Reference overlays for the shapes a project usually has
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
Reference overlays for the shapes a project usually has, for **manual mode**:
|
|
4
|
+
a project that owns its own `compose.portta.yaml` instead of the overlay
|
|
5
|
+
`portta adopt` generates (see
|
|
6
|
+
[Add an existing project](../docs/product/guides/adopting-projects.md#manual-mode)).
|
|
7
|
+
They are **references to copy from**, not runtime that projects depend on:
|
|
8
|
+
nothing here is included, mounted or extended by a consumer project. Copy the
|
|
9
|
+
closest one, adjust the service names and ports, and it is yours.
|
|
10
|
+
|
|
11
|
+
`portta envs init <path>` generates the same thing from a project's actual
|
|
9
12
|
Compose file, which is usually faster.
|
|
10
13
|
|
|
11
14
|
| Template | Shape |
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
# The original environment keeps running. Nothing inside the project changed.
|
|
16
16
|
# Derive the name instead of inventing one:
|
|
17
17
|
#
|
|
18
|
-
# portta
|
|
18
|
+
# portta envs namespace
|
|
19
19
|
# ============================================================================
|
|
20
20
|
|
|
21
21
|
COMPOSE_PROJECT_NAME=base-empresarial-issue59
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Running this project on Portta
|
|
2
2
|
|
|
3
3
|
> Copy this file into the project and adjust the names. It covers only what
|
|
4
|
-
> someone working on *this* project needs. The rules themselves live in the
|
|
5
|
-
>
|
|
4
|
+
> someone working on *this* project needs. The rules themselves live in the
|
|
5
|
+
> Portta repository, which stays the single source of truth.
|
|
6
6
|
|
|
7
7
|
## Prerequisites
|
|
8
8
|
|
|
@@ -71,7 +71,7 @@ Credentials are this project's, from its own `.env`.
|
|
|
71
71
|
## Working on two branches at once
|
|
72
72
|
|
|
73
73
|
```bash
|
|
74
|
-
git worktree add ../<project>-issue59 issue59
|
|
74
|
+
git worktree add --relative-paths ../<project>-issue59 issue59
|
|
75
75
|
cd ../<project>-issue59
|
|
76
76
|
echo "COMPOSE_PROJECT_NAME=<project>-issue59" >> .env
|
|
77
77
|
docker compose -f compose.yaml -f compose.portta.yaml up -d
|
package/dist/supervisor.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codions/portta",
|
|
3
|
-
"version": "0.0.0-develop.
|
|
3
|
+
"version": "0.0.0-develop.174.sha-9f22fb0",
|
|
4
4
|
"description": "Machine-first CLI for a shared Docker development gateway",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -19,10 +19,7 @@
|
|
|
19
19
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
20
20
|
"test": "vitest run",
|
|
21
21
|
"prepack": "npm run build",
|
|
22
|
-
"prepublishOnly": "npm run typecheck && npm test"
|
|
23
|
-
"preversion": "node scripts/git-version.mjs check",
|
|
24
|
-
"version": "node scripts/git-version.mjs sync",
|
|
25
|
-
"postversion": "node scripts/git-version.mjs verify"
|
|
22
|
+
"prepublishOnly": "npm run typecheck && npm test"
|
|
26
23
|
},
|
|
27
24
|
"engines": {
|
|
28
25
|
"node": ">=24"
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# ============================================================================
|
|
2
|
-
# Portta project protection: the working middleware is generated for you
|
|
3
|
-
# ============================================================================
|
|
4
|
-
# Do not copy this file into the dynamic directory. `portta-auth.yaml` already
|
|
5
|
-
# defines `portta-forward-auth`; this disabled example documents the project
|
|
6
|
-
# label that opts one existing router into it.
|
|
7
|
-
#
|
|
8
|
-
# 1. Create or rotate the host credential:
|
|
9
|
-
#
|
|
10
|
-
# portta auth protect demo-web.example.com --project demo --service web
|
|
11
|
-
#
|
|
12
|
-
# 2. Add the middleware to that project's own router:
|
|
13
|
-
#
|
|
14
|
-
# labels:
|
|
15
|
-
# - "traefik.http.routers.demo-web.middlewares=portta-forward-auth@file"
|
|
16
|
-
#
|
|
17
|
-
# Portta deliberately does not edit a consumer project's labels. The project
|
|
18
|
-
# owns that router; Portta owns only the credential, login route and ForwardAuth
|
|
19
|
-
# middleware. `/__portta/auth` is reserved on every protected hostname.
|
|
20
|
-
#
|
|
21
|
-
# To remove the credential (the project label remains yours to remove):
|
|
22
|
-
#
|
|
23
|
-
# portta auth unprotect demo-web.example.com
|
|
24
|
-
# ============================================================================
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# Operational images
|
|
2
|
-
|
|
3
|
-
These directories are self-contained build contexts for images used by the
|
|
4
|
-
Portta runtime rather than by a Compose service directly:
|
|
5
|
-
|
|
6
|
-
- `apply/` builds the opt-in applier that recreates the gateway after settings
|
|
7
|
-
change.
|
|
8
|
-
- `toolbox/` builds the pinned diagnostic and database-client toolbox.
|
|
9
|
-
|
|
10
|
-
Application images stay with their applications. In particular,
|
|
11
|
-
`apps/web/Dockerfile` remains under `apps/web` because it builds the web and
|
|
12
|
-
authentication workspaces from the repository-root context.
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# syntax=docker/dockerfile:1.7
|
|
2
|
-
|
|
3
|
-
FROM node:24-bookworm-slim
|
|
4
|
-
|
|
5
|
-
ENV AWS_DEFAULT_REGION=auto \
|
|
6
|
-
DEBIAN_FRONTEND=noninteractive \
|
|
7
|
-
DISABLE_UPDATES=1 \
|
|
8
|
-
NPM_CONFIG_PREFIX=/usr/local \
|
|
9
|
-
PATH="/root/.local/bin:/usr/local/bin:/root/.bun/bin:/root/.cargo/bin:${PATH}" \
|
|
10
|
-
PLAYWRIGHT_BROWSERS_PATH=/ms-playwright \
|
|
11
|
-
PORTTA_FLOW_SANDBOX_MANIFEST=/etc/taskflow-sandbox/manifest.json
|
|
12
|
-
|
|
13
|
-
RUN apt-get update \
|
|
14
|
-
&& apt-get install -y --no-install-recommends \
|
|
15
|
-
build-essential \
|
|
16
|
-
ca-certificates \
|
|
17
|
-
curl \
|
|
18
|
-
git \
|
|
19
|
-
gnupg \
|
|
20
|
-
groff \
|
|
21
|
-
jq \
|
|
22
|
-
less \
|
|
23
|
-
openssh-client \
|
|
24
|
-
ripgrep \
|
|
25
|
-
sudo \
|
|
26
|
-
unzip \
|
|
27
|
-
&& rm -rf /var/lib/apt/lists/*
|
|
28
|
-
|
|
29
|
-
ARG TARGETARCH
|
|
30
|
-
ARG ASCIINEMA_VERSION=3.2.1
|
|
31
|
-
ARG ASCIINEMA_SHA256_AMD64=1b405bbda565b33c3c4718de67fedc3535580603c0694b1ff3fb04f363430a20
|
|
32
|
-
ARG ASCIINEMA_SHA256_ARM64=b516a6d896844c0ffbc96e0a55afe4cbcc79216abde0fc64fdda4e39bee421ea
|
|
33
|
-
|
|
34
|
-
RUN case "${TARGETARCH}" in \
|
|
35
|
-
amd64) target=x86_64; sha256="${ASCIINEMA_SHA256_AMD64}" ;; \
|
|
36
|
-
arm64) target=aarch64; sha256="${ASCIINEMA_SHA256_ARM64}" ;; \
|
|
37
|
-
*) echo "Unsupported asciinema architecture: ${TARGETARCH}" >&2; exit 1 ;; \
|
|
38
|
-
esac \
|
|
39
|
-
&& curl -fsSL -o /usr/local/bin/asciinema \
|
|
40
|
-
"https://github.com/asciinema/asciinema/releases/download/v${ASCIINEMA_VERSION}/asciinema-${target}-unknown-linux-gnu" \
|
|
41
|
-
&& echo "${sha256} /usr/local/bin/asciinema" | sha256sum -c - \
|
|
42
|
-
&& chmod 0755 /usr/local/bin/asciinema
|
|
43
|
-
|
|
44
|
-
COPY --chmod=0755 agents/ /usr/local/lib/taskflow-sandbox/agents/
|
|
45
|
-
COPY --chmod=0755 scripts/ /usr/local/lib/taskflow-sandbox/scripts/
|
|
46
|
-
|
|
47
|
-
ARG BUILD_DATE=unknown
|
|
48
|
-
ARG BUILD_ID=local
|
|
49
|
-
ARG SANDBOX_VERSION=dev
|
|
50
|
-
ARG TOOLS_REFRESH=local
|
|
51
|
-
ARG VCS_REF=unknown
|
|
52
|
-
|
|
53
|
-
# TOOLS_REFRESH deliberately invalidates only the high-cadence tool layer.
|
|
54
|
-
RUN echo "Refreshing volatile tools: ${TOOLS_REFRESH}" \
|
|
55
|
-
&& TARGETARCH="${TARGETARCH}" /usr/local/lib/taskflow-sandbox/scripts/install-tools.sh \
|
|
56
|
-
&& install -d -m 0755 /etc/taskflow-sandbox \
|
|
57
|
-
&& SANDBOX_VERSION="${SANDBOX_VERSION}" \
|
|
58
|
-
BUILD_DATE="${BUILD_DATE}" \
|
|
59
|
-
BUILD_ID="${BUILD_ID}" \
|
|
60
|
-
VCS_REF="${VCS_REF}" \
|
|
61
|
-
node /usr/local/lib/taskflow-sandbox/scripts/generate-manifest.mjs "${PORTTA_FLOW_SANDBOX_MANIFEST}" \
|
|
62
|
-
&& /usr/local/lib/taskflow-sandbox/scripts/verify-image.sh
|
|
63
|
-
|
|
64
|
-
# Task Flow runs containers with the host UID/GID. Keep HOME traversable and
|
|
65
|
-
# writable while tools remain installed read-only under /usr/local.
|
|
66
|
-
RUN usermod -l agent -d /root -s /bin/bash node \
|
|
67
|
-
&& echo "agent ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/agent \
|
|
68
|
-
&& chmod 0440 /etc/sudoers.d/agent \
|
|
69
|
-
&& chmod -R 0777 /root /ms-playwright \
|
|
70
|
-
&& ln -sf /usr/local/lib/taskflow-sandbox/scripts/entrypoint.sh /usr/local/bin/entrypoint.sh
|
|
71
|
-
|
|
72
|
-
LABEL org.opencontainers.image.created="${BUILD_DATE}" \
|
|
73
|
-
org.opencontainers.image.description="Universal Task Flow agent sandbox" \
|
|
74
|
-
org.opencontainers.image.revision="${VCS_REF}" \
|
|
75
|
-
org.opencontainers.image.source="https://github.com/codions-labs/task-flow" \
|
|
76
|
-
org.opencontainers.image.title="Task Flow Sandbox" \
|
|
77
|
-
org.opencontainers.image.version="${SANDBOX_VERSION}"
|
|
78
|
-
|
|
79
|
-
CMD ["sleep", "infinity"]
|