pi-deck 0.1.4 → 0.1.5

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/server.js CHANGED
@@ -24,8 +24,8 @@ __export(plan_service_exports, {
24
24
  writePlan: () => writePlan
25
25
  });
26
26
  import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync, readdirSync as readdirSync2 } from "fs";
27
- import { join as join3, basename as basename2, resolve as resolve2 } from "path";
28
- import { homedir as homedir2 } from "os";
27
+ import { join as join3, basename, resolve as resolve2 } from "path";
28
+ import { homedir as homedir3 } from "os";
29
29
  function parseFrontmatter(content) {
30
30
  const frontmatter = {};
31
31
  if (!content.startsWith("---")) {
@@ -88,7 +88,7 @@ function parseTasks(content) {
88
88
  function parsePlan(filePath, content) {
89
89
  const { frontmatter } = parseFrontmatter(content);
90
90
  const tasks = parseTasks(content);
91
- const fileName = basename2(filePath, ".md");
91
+ const fileName = basename(filePath, ".md");
92
92
  let title = frontmatter.title;
93
93
  if (!title) {
94
94
  const h1Match = content.match(/^#\s+(.+)$/m);
@@ -161,9 +161,9 @@ ${fmBlock}
161
161
  ---${content.slice(endIndex + 4)}`;
162
162
  }
163
163
  function getPlanDirectories(workspacePath) {
164
- const workspaceName = basename2(workspacePath);
164
+ const workspaceName = basename(workspacePath);
165
165
  const dirs = [];
166
- const globalDir = join3(homedir2(), "plans", workspaceName);
166
+ const globalDir = join3(homedir3(), "plans", workspaceName);
167
167
  dirs.push(globalDir);
168
168
  const localDir = join3(workspacePath, ".pi", "plans");
169
169
  dirs.push(localDir);
@@ -268,8 +268,8 @@ __export(job_service_exports, {
268
268
  writeJob: () => writeJob
269
269
  });
270
270
  import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2, readdirSync as readdirSync3, mkdirSync, renameSync } from "fs";
271
- import { join as join4, basename as basename3, resolve as resolve3, dirname as dirname2 } from "path";
272
- import { homedir as homedir3 } from "os";
271
+ import { join as join4, basename as basename2, resolve as resolve3, dirname as dirname2 } from "path";
272
+ import { homedir as homedir4 } from "os";
273
273
  import YAML from "yaml";
274
274
  function statusToPhase(status) {
275
275
  switch (status) {
@@ -366,7 +366,7 @@ function parseJobFrontmatter(content) {
366
366
  function parseJob(filePath, content) {
367
367
  const { frontmatter } = parseJobFrontmatter(content);
368
368
  const tasks = parseTasks(content);
369
- const fileName = basename3(filePath, ".md");
369
+ const fileName = basename2(filePath, ".md");
370
370
  let title = frontmatter.title;
371
371
  if (!title) {
372
372
  const h1Match = content.match(/^#\s+(.+)$/m);
@@ -434,9 +434,9 @@ function updateTaskInContent2(content, lineNumber, done) {
434
434
  return lines.join("\n");
435
435
  }
436
436
  function getJobDirectories(workspacePath) {
437
- const workspaceName = basename3(workspacePath);
437
+ const workspaceName = basename2(workspacePath);
438
438
  const dirs = [];
439
- dirs.push(join4(homedir3(), ".pi", "agent", "jobs", workspaceName));
439
+ dirs.push(join4(homedir4(), ".pi", "agent", "jobs", workspaceName));
440
440
  dirs.push(join4(workspacePath, ".pi", "jobs"));
441
441
  return dirs;
442
442
  }
@@ -491,8 +491,8 @@ function writeJob(jobPath, content) {
491
491
  return parseJob(jobPath, content);
492
492
  }
493
493
  function createJob(workspacePath, title, description, tags) {
494
- const workspaceName = basename3(workspacePath);
495
- const jobsDir = join4(homedir3(), ".pi", "agent", "jobs", workspaceName);
494
+ const workspaceName = basename2(workspacePath);
495
+ const jobsDir = join4(homedir4(), ".pi", "agent", "jobs", workspaceName);
496
496
  if (!existsSync4(jobsDir)) {
497
497
  mkdirSync(jobsDir, { recursive: true });
498
498
  }
@@ -579,7 +579,7 @@ function getArchivedDir(jobDir) {
579
579
  }
580
580
  function archiveJob(jobPath) {
581
581
  const dir = dirname2(jobPath);
582
- const file = basename3(jobPath);
582
+ const file = basename2(jobPath);
583
583
  const archivedDir = getArchivedDir(dir);
584
584
  if (!existsSync4(archivedDir)) {
585
585
  mkdirSync(archivedDir, { recursive: true });
@@ -591,7 +591,7 @@ function archiveJob(jobPath) {
591
591
  function unarchiveJob(jobPath) {
592
592
  const archivedDir = dirname2(jobPath);
593
593
  const parentDir = dirname2(archivedDir);
594
- const file = basename3(jobPath);
594
+ const file = basename2(jobPath);
595
595
  const newPath = join4(parentDir, file);
596
596
  renameSync(jobPath, newPath);
597
597
  return newPath;
@@ -764,10 +764,10 @@ import { createServer } from "http";
764
764
  import { WebSocketServer, WebSocket } from "ws";
765
765
  import { fileURLToPath } from "url";
766
766
  import { dirname as dirname5, join as join7, resolve as resolve4, sep } from "path";
767
- import { existsSync as existsSync9, readFileSync as readFileSync4, writeFileSync as writeFileSync3, readdirSync as readdirSync5, statSync as statSync3 } from "fs";
767
+ import { existsSync as existsSync9, readFileSync as readFileSync4, readdirSync as readdirSync5, statSync as statSync3 } from "fs";
768
768
  import { unlink } from "fs/promises";
769
769
  import { spawn } from "child_process";
770
- import { homedir as homedir5 } from "os";
770
+ import { homedir as homedir6 } from "os";
771
771
  import { SessionManager as SessionManager2 } from "@mariozechner/pi-coding-agent";
772
772
 
773
773
  // packages/server/dist/config.js
@@ -801,9 +801,7 @@ function findProjectRoot(startDir) {
801
801
  var projectRoot = findProjectRoot(process.cwd());
802
802
  var DEFAULT_CONFIG = {
803
803
  port: 9741,
804
- host: "0.0.0.0",
805
- // Default to detected project root, then home as fallback
806
- allowedDirectories: [projectRoot, homedir()]
804
+ host: "0.0.0.0"
807
805
  };
808
806
  var CONFIG_PATHS = [
809
807
  resolve(process.cwd(), "pi-deck.config.json"),
@@ -833,9 +831,6 @@ function loadConfigFromEnv() {
833
831
  if (process.env.HOST) {
834
832
  config2.host = process.env.HOST;
835
833
  }
836
- if (process.env.PI_ALLOWED_DIRS) {
837
- config2.allowedDirectories = process.env.PI_ALLOWED_DIRS.split(":").map((d) => resolve(d.replace(/^~/, homedir())));
838
- }
839
834
  return config2;
840
835
  }
841
836
  var TILDE_PREFIX = /^~(?=\/|$)/;
@@ -847,57 +842,36 @@ function canonicalizePath(input) {
847
842
  return normalized;
848
843
  }
849
844
  }
850
- function normalizeDirectories(dirs) {
851
- return dirs.map((d) => canonicalizePath(d));
852
- }
853
845
  function loadConfig() {
854
846
  const fileConfig = loadConfigFromFile();
855
847
  const envConfig = loadConfigFromEnv();
856
848
  const config2 = {
857
849
  port: envConfig.port ?? fileConfig.port ?? DEFAULT_CONFIG.port,
858
- host: envConfig.host ?? fileConfig.host ?? DEFAULT_CONFIG.host,
859
- allowedDirectories: normalizeDirectories(envConfig.allowedDirectories ?? fileConfig.allowedDirectories ?? DEFAULT_CONFIG.allowedDirectories)
850
+ host: envConfig.host ?? fileConfig.host ?? DEFAULT_CONFIG.host
860
851
  };
861
- console.log("[Config] Allowed directories:", config2.allowedDirectories);
862
852
  return config2;
863
853
  }
864
- function isPathAllowed(path, allowedDirectories) {
865
- const normalizedPath = canonicalizePath(path);
866
- return allowedDirectories.some((allowed) => {
867
- const normalizedAllowed = canonicalizePath(allowed);
868
- if (normalizedAllowed === "/") {
869
- return true;
870
- }
871
- return normalizedPath === normalizedAllowed || normalizedPath.startsWith(normalizedAllowed + "/");
872
- });
873
- }
874
854
 
875
855
  // packages/server/dist/directory-browser.js
876
856
  import { readdirSync, statSync, existsSync as existsSync2 } from "fs";
877
- import { basename, join as join2 } from "path";
857
+ import { join as join2 } from "path";
858
+ import { homedir as homedir2 } from "os";
878
859
  var DirectoryBrowser = class {
879
- allowedDirectories;
880
- constructor(allowedDirectories) {
881
- this.allowedDirectories = allowedDirectories;
882
- }
883
860
  /**
884
861
  * List the allowed root directories
885
862
  */
886
863
  listRoots() {
887
- return this.allowedDirectories.map((dir) => ({
888
- name: basename(dir) || dir,
889
- path: dir,
890
- hasPiSessions: this.checkForPiSessions(dir)
891
- }));
864
+ return [{
865
+ name: "Home",
866
+ path: homedir2(),
867
+ hasPiSessions: this.checkForPiSessions(homedir2())
868
+ }];
892
869
  }
893
870
  /**
894
871
  * Browse a directory and return its subdirectories
895
872
  */
896
873
  browse(path) {
897
874
  const normalizedPath = canonicalizePath(path);
898
- if (!isPathAllowed(normalizedPath, this.allowedDirectories)) {
899
- throw new Error(`Access denied: ${path} is not within allowed directories`);
900
- }
901
875
  if (!existsSync2(normalizedPath)) {
902
876
  throw new Error(`Directory not found: ${path}`);
903
877
  }
@@ -942,13 +916,13 @@ var DirectoryBrowser = class {
942
916
  * Get the allowed directories
943
917
  */
944
918
  getAllowedDirectories() {
945
- return [...this.allowedDirectories];
919
+ return [homedir2()];
946
920
  }
947
921
  };
948
922
 
949
923
  // packages/server/dist/workspace-manager.js
950
924
  import { EventEmitter as EventEmitter3 } from "events";
951
- import { basename as basename4 } from "path";
925
+ import { basename as basename3 } from "path";
952
926
 
953
927
  // packages/server/dist/session-orchestrator.js
954
928
  import { EventEmitter as EventEmitter2 } from "events";
@@ -2975,14 +2949,12 @@ var SessionOrchestrator = class extends EventEmitter2 {
2975
2949
 
2976
2950
  // packages/server/dist/workspace-manager.js
2977
2951
  var WorkspaceManager = class extends EventEmitter3 {
2978
- allowedDirectories;
2979
2952
  workspaces = /* @__PURE__ */ new Map();
2980
2953
  nextWorkspaceId = 1;
2981
2954
  syncIntegration = null;
2982
2955
  openingPaths = /* @__PURE__ */ new Set();
2983
- constructor(allowedDirectories) {
2956
+ constructor() {
2984
2957
  super();
2985
- this.allowedDirectories = allowedDirectories;
2986
2958
  }
2987
2959
  /**
2988
2960
  * Set the sync integration for state tracking
@@ -2997,9 +2969,6 @@ var WorkspaceManager = class extends EventEmitter3 {
2997
2969
  */
2998
2970
  async openWorkspace(path) {
2999
2971
  const normalizedPath = canonicalizePath(path);
3000
- if (!isPathAllowed(normalizedPath, this.allowedDirectories)) {
3001
- throw new Error(`Access denied: ${normalizedPath} is not within allowed directories`);
3002
- }
3003
2972
  while (this.openingPaths.has(normalizedPath)) {
3004
2973
  await new Promise((resolve5) => setTimeout(resolve5, 10));
3005
2974
  }
@@ -3044,7 +3013,7 @@ var WorkspaceManager = class extends EventEmitter3 {
3044
3013
  const workspace = {
3045
3014
  id,
3046
3015
  path: normalizedPath,
3047
- name: basename4(normalizedPath) || normalizedPath,
3016
+ name: basename3(normalizedPath) || normalizedPath,
3048
3017
  orchestrator,
3049
3018
  unsubscribe,
3050
3019
  clientCount: 1,
@@ -3258,9 +3227,9 @@ var WorkspaceManager = class extends EventEmitter3 {
3258
3227
  }
3259
3228
  };
3260
3229
  var workspaceManager = null;
3261
- function getWorkspaceManager(allowedDirectories) {
3230
+ function getWorkspaceManager() {
3262
3231
  if (!workspaceManager) {
3263
- workspaceManager = new WorkspaceManager(allowedDirectories);
3232
+ workspaceManager = new WorkspaceManager();
3264
3233
  }
3265
3234
  return workspaceManager;
3266
3235
  }
@@ -3268,7 +3237,7 @@ function getWorkspaceManager(allowedDirectories) {
3268
3237
  // packages/server/dist/ui-state.js
3269
3238
  import Database from "better-sqlite3";
3270
3239
  import { existsSync as existsSync6, mkdirSync as mkdirSync2 } from "fs";
3271
- import { homedir as homedir4 } from "os";
3240
+ import { homedir as homedir5 } from "os";
3272
3241
  import { dirname as dirname3, join as join5 } from "path";
3273
3242
  var DEFAULT_STATE = {
3274
3243
  openWorkspaces: [],
@@ -3287,7 +3256,7 @@ var DEFAULT_STATE = {
3287
3256
  var UIStateStore = class {
3288
3257
  db;
3289
3258
  constructor(dbPath) {
3290
- const path = dbPath || join5(homedir4(), ".config", "pi-deck", "ui-state.db");
3259
+ const path = dbPath || join5(homedir5(), ".config", "pi-deck", "ui-state.db");
3291
3260
  const dir = dirname3(path);
3292
3261
  if (!existsSync6(dir)) {
3293
3262
  mkdirSync2(dir, { recursive: true });
@@ -5179,7 +5148,7 @@ var SyncIntegration = class extends EventEmitter8 {
5179
5148
 
5180
5149
  // packages/server/dist/index.js
5181
5150
  var config = loadConfig();
5182
- var syncDbPath = join7(homedir5(), ".pi", "pi-deck-sync.db");
5151
+ var syncDbPath = join7(homedir6(), ".pi", "pi-deck-sync.db");
5183
5152
  var syncIntegration = new SyncIntegration(syncDbPath);
5184
5153
  console.log(`[Sync] Initialized sync database at ${syncDbPath}`);
5185
5154
  var PORT = config.port;
@@ -5219,9 +5188,9 @@ if (existsSync9(clientDistPath)) {
5219
5188
  }
5220
5189
  var server = createServer(app);
5221
5190
  var wss = new WebSocketServer({ server, path: "/ws" });
5222
- var directoryBrowser = new DirectoryBrowser(config.allowedDirectories);
5191
+ var directoryBrowser = new DirectoryBrowser();
5223
5192
  var uiStateStore = getUIStateStore();
5224
- var workspaceManager2 = getWorkspaceManager(config.allowedDirectories);
5193
+ var workspaceManager2 = getWorkspaceManager();
5225
5194
  workspaceManager2.setSyncIntegration(syncIntegration);
5226
5195
  var clientWorkspaces = /* @__PURE__ */ new Map();
5227
5196
  var pendingQuestionnaireRoutes = /* @__PURE__ */ new Map();
@@ -5360,7 +5329,6 @@ Please read the job file and execute the review steps.`;
5360
5329
  app.get("/health", (_req, res) => {
5361
5330
  res.json({
5362
5331
  status: "ok",
5363
- allowedDirectories: config.allowedDirectories,
5364
5332
  activeWorkspaces: workspaceManager2.listWorkspaces().length
5365
5333
  });
5366
5334
  });
@@ -5372,8 +5340,7 @@ wss.on("connection", async (ws) => {
5372
5340
  send(ws, {
5373
5341
  type: "connected",
5374
5342
  workspaces: existingWorkspaces,
5375
- allowedRoots: config.allowedDirectories,
5376
- homeDirectory: homedir5(),
5343
+ homeDirectory: homedir6(),
5377
5344
  uiState,
5378
5345
  ...updateAvailable ? { updateAvailable } : {}
5379
5346
  });
@@ -5520,8 +5487,7 @@ async function handleMessage(ws, message) {
5520
5487
  send(ws, {
5521
5488
  type: "directoryList",
5522
5489
  path: "/",
5523
- entries: directoryBrowser.listRoots(),
5524
- allowedRoots: directoryBrowser.getAllowedDirectories()
5490
+ entries: directoryBrowser.listRoots()
5525
5491
  });
5526
5492
  }
5527
5493
  break;
@@ -6183,26 +6149,6 @@ ${planNote}` : planNote;
6183
6149
  });
6184
6150
  break;
6185
6151
  }
6186
- case "updateAllowedRoots": {
6187
- const { roots } = message;
6188
- console.log("[Config] Updating allowed roots:", roots);
6189
- const configPath = join7(homedir5(), ".pi-deck.json");
6190
- let fileConfig = {};
6191
- try {
6192
- if (existsSync9(configPath)) {
6193
- fileConfig = JSON.parse(readFileSync4(configPath, "utf-8"));
6194
- }
6195
- } catch {
6196
- }
6197
- fileConfig.allowedDirectories = roots;
6198
- writeFileSync3(configPath, JSON.stringify(fileConfig, null, 2));
6199
- console.log("[Config] Saved config to", configPath);
6200
- send(ws, {
6201
- type: "allowedRootsUpdated",
6202
- roots
6203
- });
6204
- break;
6205
- }
6206
6152
  // ========================================================================
6207
6153
  // Session Tree Navigation
6208
6154
  // ========================================================================
@@ -6433,26 +6379,13 @@ ${planNote}` : planNote;
6433
6379
  }
6434
6380
  const rootPath = resolve4(workspace.path);
6435
6381
  const rawPath = message.path || "";
6436
- const expandedPath = rawPath.startsWith("~/") ? join7(homedir5(), rawPath.slice(2)) : rawPath;
6382
+ const expandedPath = rawPath.startsWith("~/") ? join7(homedir6(), rawPath.slice(2)) : rawPath;
6437
6383
  const isAbsolute = expandedPath.startsWith("/");
6438
6384
  let targetPath;
6439
6385
  let displayPath;
6440
6386
  if (isAbsolute) {
6441
6387
  targetPath = resolve4(expandedPath);
6442
6388
  displayPath = rawPath;
6443
- const inWorkspace = targetPath.startsWith(rootPath + sep) || targetPath === rootPath;
6444
- const inAllowed = config.allowedDirectories.some((dir) => targetPath.startsWith(resolve4(dir) + sep) || targetPath === resolve4(dir));
6445
- if (!inWorkspace && !inAllowed) {
6446
- send(ws, {
6447
- type: "workspaceFile",
6448
- workspaceId: message.workspaceId,
6449
- path: displayPath,
6450
- content: "",
6451
- truncated: false,
6452
- requestId: message.requestId
6453
- });
6454
- break;
6455
- }
6456
6389
  } else {
6457
6390
  const relativePath = rawPath.replace(/^\/+/, "");
6458
6391
  targetPath = resolve4(rootPath, relativePath);
@@ -7319,7 +7252,6 @@ if (existsSync9(clientDistPath)) {
7319
7252
  }
7320
7253
  server.listen(PORT, config.host, () => {
7321
7254
  console.log(`[Server] Pi-Deck server running on http://${config.host}:${PORT}`);
7322
- console.log(`[Server] Allowed directories: ${config.allowedDirectories.join(", ")}`);
7323
7255
  console.log(`[Server] WebSocket endpoint: ws://${config.host}:${PORT}/ws`);
7324
7256
  });
7325
7257
  //# sourceMappingURL=server.js.map