tycono 0.1.6 → 0.1.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tycono",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Build an AI company. Watch them work.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  import { Router, Request, Response, NextFunction } from 'express';
2
2
  import { COMPANY_ROOT } from '../services/file-reader.js';
3
- import { getGitStatus, gitSave, gitHistory, gitRestore } from '../services/git-save.js';
3
+ import { getGitStatus, gitSave, gitHistory, gitRestore, gitInit } from '../services/git-save.js';
4
4
 
5
5
  export const saveRouter = Router();
6
6
 
@@ -38,6 +38,20 @@ saveRouter.get('/history', (req: Request, res: Response, next: NextFunction) =>
38
38
  }
39
39
  });
40
40
 
41
+ // POST /api/save/init — initialize git repo
42
+ saveRouter.post('/init', (_req: Request, res: Response, next: NextFunction) => {
43
+ try {
44
+ const result = gitInit(COMPANY_ROOT);
45
+ if (!result.ok) {
46
+ res.status(500).json({ error: result.message });
47
+ return;
48
+ }
49
+ res.json(result);
50
+ } catch (err) {
51
+ next(err);
52
+ }
53
+ });
54
+
41
55
  // POST /api/save/restore
42
56
  saveRouter.post('/restore', (req: Request, res: Response, next: NextFunction) => {
43
57
  try {
@@ -65,14 +65,14 @@ const SAVE_PATHS = [
65
65
 
66
66
  function run(cmd: string, cwd: string): string {
67
67
  try {
68
- return execSync(cmd, { cwd, encoding: 'utf-8', timeout: 30000 }).trim();
68
+ return execSync(cmd, { cwd, encoding: 'utf-8', timeout: 30000, stdio: ['pipe', 'pipe', 'pipe'] }).trim();
69
69
  } catch {
70
70
  return '';
71
71
  }
72
72
  }
73
73
 
74
74
  function runOrThrow(cmd: string, cwd: string): string {
75
- return execSync(cmd, { cwd, encoding: 'utf-8', timeout: 30000 }).trim();
75
+ return execSync(cmd, { cwd, encoding: 'utf-8', timeout: 30000, stdio: ['pipe', 'pipe', 'pipe'] }).trim();
76
76
  }
77
77
 
78
78
  /** Check if directory is a git repository */
@@ -80,6 +80,21 @@ function isGitRepo(root: string): boolean {
80
80
  return run('git rev-parse --is-inside-work-tree', root) === 'true';
81
81
  }
82
82
 
83
+ /** Initialize a new git repository */
84
+ export function gitInit(root: string): { ok: boolean; message: string } {
85
+ if (isGitRepo(root)) {
86
+ return { ok: true, message: 'Already a git repository' };
87
+ }
88
+ try {
89
+ runOrThrow('git init', root);
90
+ runOrThrow('git add -A', root);
91
+ runOrThrow('git commit -m "Initial commit by Tycono"', root);
92
+ return { ok: true, message: 'Git repository initialized with initial commit' };
93
+ } catch (err) {
94
+ return { ok: false, message: err instanceof Error ? err.message : 'git init failed' };
95
+ }
96
+ }
97
+
83
98
  /** Get current git status. Returns noGit=true if not a git repo. */
84
99
  export function getGitStatus(root: string): GitStatus {
85
100
  if (!isGitRepo(root)) {
@@ -29,12 +29,31 @@ export interface FurnitureOverride {
29
29
  offsetY: number;
30
30
  }
31
31
 
32
+ export interface DeskOverride {
33
+ dx: number;
34
+ dy: number;
35
+ }
36
+
37
+ export interface AddedFurniture {
38
+ id: string;
39
+ type: string;
40
+ room: string;
41
+ zone: 'wall' | 'floor';
42
+ anchorX?: 'left' | 'right';
43
+ offsetX: number;
44
+ offsetY: number;
45
+ accent?: string;
46
+ }
47
+
32
48
  export interface Preferences {
33
49
  appearances: Record<string, CharacterAppearance>;
34
50
  theme: string;
35
51
  speech?: SpeechSettings;
36
52
  language?: string; // 'en' | 'ko' | 'ja' | 'auto'
37
53
  furnitureOverrides?: Record<string, FurnitureOverride>; // keyed by FurnitureDef.id
54
+ deskOverrides?: Record<string, DeskOverride>; // keyed by role id
55
+ removedFurniture?: string[]; // FurnitureDef.id list
56
+ addedFurniture?: AddedFurniture[];
38
57
  }
39
58
 
40
59
  const CONFIG_DIR = '.tycono';
@@ -57,6 +76,9 @@ export function readPreferences(companyRoot: string): Preferences {
57
76
  speech: data.speech ?? undefined,
58
77
  language: data.language ?? undefined,
59
78
  furnitureOverrides: data.furnitureOverrides ?? undefined,
79
+ deskOverrides: data.deskOverrides ?? undefined,
80
+ removedFurniture: data.removedFurniture ?? undefined,
81
+ addedFurniture: data.addedFurniture ?? undefined,
60
82
  };
61
83
  } catch {
62
84
  return { ...DEFAULT, appearances: {} };
@@ -85,6 +107,15 @@ export function mergePreferences(companyRoot: string, partial: Partial<Preferenc
85
107
  furnitureOverrides: partial.furnitureOverrides !== undefined
86
108
  ? { ...current.furnitureOverrides, ...partial.furnitureOverrides }
87
109
  : current.furnitureOverrides,
110
+ deskOverrides: partial.deskOverrides !== undefined
111
+ ? { ...current.deskOverrides, ...partial.deskOverrides }
112
+ : current.deskOverrides,
113
+ removedFurniture: partial.removedFurniture !== undefined
114
+ ? partial.removedFurniture
115
+ : current.removedFurniture,
116
+ addedFurniture: partial.addedFurniture !== undefined
117
+ ? partial.addedFurniture
118
+ : current.addedFurniture,
88
119
  };
89
120
  writePreferences(companyRoot, merged);
90
121
  return merged;