openkitt 0.1.9 → 0.2.1

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.
Files changed (2) hide show
  1. package/dist/cli.js +170 -133
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -2802,7 +2802,7 @@ import { createInterface, emitKeypressEvents } from "node:readline";
2802
2802
  import { stdin as input, stdout as output } from "node:process";
2803
2803
  import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5, realpathSync } from "node:fs";
2804
2804
  import { homedir as homedir3 } from "node:os";
2805
- import { basename, join as join6 } from "node:path";
2805
+ import { join as join6, resolve as resolve2, dirname as dirname3 } from "node:path";
2806
2806
  import { pathToFileURL } from "node:url";
2807
2807
 
2808
2808
  // src/utils/prerequisites.ts
@@ -2894,6 +2894,112 @@ async function displayLlmStatus() {
2894
2894
  }
2895
2895
  }
2896
2896
 
2897
+ // src/manifest/reader.ts
2898
+ import { existsSync as existsSync3, readFileSync as readFileSync4 } from "node:fs";
2899
+ import { join as join3, dirname, resolve } from "node:path";
2900
+
2901
+ // src/utils/global-config.ts
2902
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
2903
+ import { homedir as homedir2 } from "node:os";
2904
+ import { join as join2 } from "node:path";
2905
+ function getGlobalConfigPath() {
2906
+ return join2(homedir2(), ".kitt", "workspace.json");
2907
+ }
2908
+ function readGlobalConfig() {
2909
+ const configPath = getGlobalConfigPath();
2910
+ if (!existsSync2(configPath)) {
2911
+ return {};
2912
+ }
2913
+ try {
2914
+ const raw = readFileSync3(configPath, "utf-8").trim();
2915
+ if (!raw)
2916
+ return {};
2917
+ const parsed = JSON.parse(raw);
2918
+ if (typeof parsed === "object" && parsed !== null) {
2919
+ return parsed;
2920
+ }
2921
+ return {};
2922
+ } catch {
2923
+ return {};
2924
+ }
2925
+ }
2926
+ function getGlobalWorkspacePath() {
2927
+ return readGlobalConfig().workspacePath ?? null;
2928
+ }
2929
+
2930
+ // src/manifest/reader.ts
2931
+ function isObjectRecord(value) {
2932
+ return typeof value === "object" && value !== null;
2933
+ }
2934
+ function isValidWorkspaceManifest(value) {
2935
+ if (!isObjectRecord(value)) {
2936
+ return false;
2937
+ }
2938
+ if (typeof value.version !== "string") {
2939
+ return false;
2940
+ }
2941
+ if (!isObjectRecord(value.workspace)) {
2942
+ return false;
2943
+ }
2944
+ if (typeof value.workspace.name !== "string") {
2945
+ return false;
2946
+ }
2947
+ const packageManager = value.workspace.packageManager;
2948
+ if (packageManager !== "bun" && packageManager !== "npm" && packageManager !== "pnpm" && packageManager !== "yarn") {
2949
+ return false;
2950
+ }
2951
+ if (!isObjectRecord(value.apps)) {
2952
+ return false;
2953
+ }
2954
+ if (!isObjectRecord(value.packages)) {
2955
+ return false;
2956
+ }
2957
+ if (!isObjectRecord(value.settings)) {
2958
+ return false;
2959
+ }
2960
+ return true;
2961
+ }
2962
+ function getManifestPath(workspaceDir) {
2963
+ return join3(workspaceDir, ".kitt", "manifest.json");
2964
+ }
2965
+ function isKittWorkspace(dir) {
2966
+ return existsSync3(getManifestPath(dir));
2967
+ }
2968
+ function findWorkspaceRoot(startDir) {
2969
+ let current = resolve(startDir);
2970
+ while (true) {
2971
+ if (isKittWorkspace(current))
2972
+ return current;
2973
+ const parent = dirname(current);
2974
+ if (parent === current)
2975
+ break;
2976
+ current = parent;
2977
+ }
2978
+ const globalPath = getGlobalWorkspacePath();
2979
+ if (globalPath && isKittWorkspace(globalPath))
2980
+ return globalPath;
2981
+ return null;
2982
+ }
2983
+ function readManifest(workspaceDir) {
2984
+ const manifestPath = getManifestPath(workspaceDir);
2985
+ if (!existsSync3(manifestPath)) {
2986
+ return null;
2987
+ }
2988
+ try {
2989
+ const raw = readFileSync4(manifestPath, "utf-8").trim();
2990
+ if (raw.length === 0) {
2991
+ return null;
2992
+ }
2993
+ const parsed = JSON.parse(raw);
2994
+ if (!isValidWorkspaceManifest(parsed)) {
2995
+ return null;
2996
+ }
2997
+ return parsed;
2998
+ } catch {
2999
+ return null;
3000
+ }
3001
+ }
3002
+
2897
3003
  // src/utils/auth-guard.ts
2898
3004
  init_config();
2899
3005
 
@@ -2940,6 +3046,21 @@ async function checkRailwayAuth() {
2940
3046
  }
2941
3047
 
2942
3048
  // src/utils/auth-guard.ts
3049
+ var WORKSPACE_REQUIRED = new Set([
3050
+ "create",
3051
+ "delete",
3052
+ "list",
3053
+ "run",
3054
+ "deploy",
3055
+ "deploy:template",
3056
+ "env:create",
3057
+ "env:vars",
3058
+ "domain",
3059
+ "logs",
3060
+ "status",
3061
+ "versions",
3062
+ "publish"
3063
+ ]);
2943
3064
  var COMMAND_AUTH = {
2944
3065
  login: "none",
2945
3066
  logout: "none",
@@ -2960,6 +3081,15 @@ var COMMAND_AUTH = {
2960
3081
  status: "both"
2961
3082
  };
2962
3083
  async function checkAuthGuard(commandKey) {
3084
+ if (WORKSPACE_REQUIRED.has(commandKey)) {
3085
+ const workspaceRoot = findWorkspaceRoot(process.cwd());
3086
+ if (!workspaceRoot) {
3087
+ return {
3088
+ allowed: false,
3089
+ message: "No KITT workspace found. Run /init to initialize one."
3090
+ };
3091
+ }
3092
+ }
2963
3093
  const requirement = COMMAND_AUTH[commandKey];
2964
3094
  if (!requirement || requirement === "none") {
2965
3095
  return { allowed: true };
@@ -3128,27 +3258,27 @@ function warn(message) {
3128
3258
  // src/sandbox/staging.ts
3129
3259
  import {
3130
3260
  copyFileSync,
3131
- existsSync as existsSync3,
3132
- mkdirSync as mkdirSync3,
3261
+ existsSync as existsSync5,
3262
+ mkdirSync as mkdirSync4,
3133
3263
  readdirSync,
3134
- readFileSync as readFileSync3,
3264
+ readFileSync as readFileSync5,
3135
3265
  rmSync as rmSync2,
3136
3266
  statSync as statSync3,
3137
- writeFileSync as writeFileSync3
3267
+ writeFileSync as writeFileSync4
3138
3268
  } from "node:fs";
3139
- import { dirname, join as join3, relative } from "node:path";
3269
+ import { dirname as dirname2, join as join5, relative } from "node:path";
3140
3270
 
3141
3271
  // src/audit/logger.ts
3142
3272
  import {
3143
3273
  appendFileSync,
3144
- existsSync as existsSync2,
3145
- mkdirSync as mkdirSync2,
3274
+ existsSync as existsSync4,
3275
+ mkdirSync as mkdirSync3,
3146
3276
  renameSync as renameSync2,
3147
3277
  rmSync,
3148
3278
  statSync as statSync2,
3149
- writeFileSync as writeFileSync2
3279
+ writeFileSync as writeFileSync3
3150
3280
  } from "node:fs";
3151
- import { join as join2 } from "node:path";
3281
+ import { join as join4 } from "node:path";
3152
3282
  var AUDIT_DIR_NAME = ".kitt";
3153
3283
  var AUDIT_FILE_NAME = "audit.log";
3154
3284
  var ROTATED_LOG_1 = "audit.log.1";
@@ -3159,27 +3289,27 @@ function formatLine(type, message) {
3159
3289
  `;
3160
3290
  }
3161
3291
  function ensureAuditDir(auditDir) {
3162
- if (existsSync2(auditDir)) {
3292
+ if (existsSync4(auditDir)) {
3163
3293
  return;
3164
3294
  }
3165
- mkdirSync2(auditDir, { recursive: true, mode: 448 });
3295
+ mkdirSync3(auditDir, { recursive: true, mode: 448 });
3166
3296
  }
3167
3297
  function rotateLogIfNeeded(logPath, log1Path, log2Path) {
3168
- if (!existsSync2(logPath)) {
3298
+ if (!existsSync4(logPath)) {
3169
3299
  return;
3170
3300
  }
3171
3301
  const stats = statSync2(logPath);
3172
3302
  if (stats.size < MAX_LOG_SIZE_BYTES) {
3173
3303
  return;
3174
3304
  }
3175
- if (existsSync2(log2Path)) {
3305
+ if (existsSync4(log2Path)) {
3176
3306
  rmSync(log2Path, { force: true });
3177
3307
  }
3178
- if (existsSync2(log1Path)) {
3308
+ if (existsSync4(log1Path)) {
3179
3309
  renameSync2(log1Path, log2Path);
3180
3310
  }
3181
3311
  renameSync2(logPath, log1Path);
3182
- writeFileSync2(logPath, "", { encoding: "utf8", mode: 384 });
3312
+ writeFileSync3(logPath, "", { encoding: "utf8", mode: 384 });
3183
3313
  }
3184
3314
  function writeAuditLine(logPath, log1Path, log2Path, type, message) {
3185
3315
  try {
@@ -3190,10 +3320,10 @@ function writeAuditLine(logPath, log1Path, log2Path, type, message) {
3190
3320
  }
3191
3321
  }
3192
3322
  function createAuditLogger(workspaceDir) {
3193
- const auditDir = join2(workspaceDir, AUDIT_DIR_NAME);
3194
- const logPath = join2(auditDir, AUDIT_FILE_NAME);
3195
- const log1Path = join2(auditDir, ROTATED_LOG_1);
3196
- const log2Path = join2(auditDir, ROTATED_LOG_2);
3323
+ const auditDir = join4(workspaceDir, AUDIT_DIR_NAME);
3324
+ const logPath = join4(auditDir, AUDIT_FILE_NAME);
3325
+ const log1Path = join4(auditDir, ROTATED_LOG_1);
3326
+ const log2Path = join4(auditDir, ROTATED_LOG_2);
3197
3327
  return {
3198
3328
  log(type, message) {
3199
3329
  try {
@@ -3237,16 +3367,16 @@ function createAuditLogger(workspaceDir) {
3237
3367
  var KITT_DIR = ".kitt";
3238
3368
  var STAGING_DIR = "staging";
3239
3369
  function getStagingDir(workspaceDir) {
3240
- return join3(workspaceDir, KITT_DIR, STAGING_DIR);
3370
+ return join5(workspaceDir, KITT_DIR, STAGING_DIR);
3241
3371
  }
3242
3372
  function clearStaging(workspaceDir) {
3243
3373
  const logger = createAuditLogger(workspaceDir);
3244
3374
  const stagingDir = getStagingDir(workspaceDir);
3245
- if (existsSync3(stagingDir)) {
3375
+ if (existsSync5(stagingDir)) {
3246
3376
  rmSync2(stagingDir, { recursive: true, force: true });
3247
3377
  }
3248
- mkdirSync3(stagingDir, { recursive: true });
3249
- logger.staged(join3(KITT_DIR, STAGING_DIR), "cleared");
3378
+ mkdirSync4(stagingDir, { recursive: true });
3379
+ logger.staged(join5(KITT_DIR, STAGING_DIR), "cleared");
3250
3380
  }
3251
3381
 
3252
3382
  // src/utils/cleanup.ts
@@ -3282,116 +3412,10 @@ function registerCleanupHandlers() {
3282
3412
  handleCleanupSignal("SIGTERM");
3283
3413
  });
3284
3414
  }
3285
-
3286
- // src/manifest/reader.ts
3287
- import { existsSync as existsSync5, readFileSync as readFileSync5 } from "node:fs";
3288
- import { join as join5, dirname as dirname2, resolve } from "node:path";
3289
-
3290
- // src/utils/global-config.ts
3291
- import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "node:fs";
3292
- import { homedir as homedir2 } from "node:os";
3293
- import { join as join4 } from "node:path";
3294
- function getGlobalConfigPath() {
3295
- return join4(homedir2(), ".kitt", "workspace.json");
3296
- }
3297
- function readGlobalConfig() {
3298
- const configPath = getGlobalConfigPath();
3299
- if (!existsSync4(configPath)) {
3300
- return {};
3301
- }
3302
- try {
3303
- const raw = readFileSync4(configPath, "utf-8").trim();
3304
- if (!raw)
3305
- return {};
3306
- const parsed = JSON.parse(raw);
3307
- if (typeof parsed === "object" && parsed !== null) {
3308
- return parsed;
3309
- }
3310
- return {};
3311
- } catch {
3312
- return {};
3313
- }
3314
- }
3315
- function getGlobalWorkspacePath() {
3316
- return readGlobalConfig().workspacePath ?? null;
3317
- }
3318
-
3319
- // src/manifest/reader.ts
3320
- function isObjectRecord(value) {
3321
- return typeof value === "object" && value !== null;
3322
- }
3323
- function isValidWorkspaceManifest(value) {
3324
- if (!isObjectRecord(value)) {
3325
- return false;
3326
- }
3327
- if (typeof value.version !== "string") {
3328
- return false;
3329
- }
3330
- if (!isObjectRecord(value.workspace)) {
3331
- return false;
3332
- }
3333
- if (typeof value.workspace.name !== "string") {
3334
- return false;
3335
- }
3336
- const packageManager = value.workspace.packageManager;
3337
- if (packageManager !== "bun" && packageManager !== "npm" && packageManager !== "pnpm" && packageManager !== "yarn") {
3338
- return false;
3339
- }
3340
- if (!isObjectRecord(value.apps)) {
3341
- return false;
3342
- }
3343
- if (!isObjectRecord(value.packages)) {
3344
- return false;
3345
- }
3346
- if (!isObjectRecord(value.settings)) {
3347
- return false;
3348
- }
3349
- return true;
3350
- }
3351
- function getManifestPath(workspaceDir) {
3352
- return join5(workspaceDir, ".kitt", "manifest.json");
3353
- }
3354
- function isKittWorkspace(dir) {
3355
- return existsSync5(getManifestPath(dir));
3356
- }
3357
- function findWorkspaceRoot(startDir) {
3358
- let current = resolve(startDir);
3359
- while (true) {
3360
- if (isKittWorkspace(current))
3361
- return current;
3362
- const parent = dirname2(current);
3363
- if (parent === current)
3364
- break;
3365
- current = parent;
3366
- }
3367
- const globalPath = getGlobalWorkspacePath();
3368
- if (globalPath && isKittWorkspace(globalPath))
3369
- return globalPath;
3370
- return null;
3371
- }
3372
- function readManifest(workspaceDir) {
3373
- const manifestPath = getManifestPath(workspaceDir);
3374
- if (!existsSync5(manifestPath)) {
3375
- return null;
3376
- }
3377
- try {
3378
- const raw = readFileSync5(manifestPath, "utf-8").trim();
3379
- if (raw.length === 0) {
3380
- return null;
3381
- }
3382
- const parsed = JSON.parse(raw);
3383
- if (!isValidWorkspaceManifest(parsed)) {
3384
- return null;
3385
- }
3386
- return parsed;
3387
- } catch {
3388
- return null;
3389
- }
3390
- }
3391
3415
  // package.json
3392
3416
  var package_default = {
3393
3417
  name: "openkitt",
3394
- version: "0.1.9",
3418
+ version: "0.2.1",
3395
3419
  description: "AI-powered monorepo scaffolding CLI",
3396
3420
  keywords: [
3397
3421
  "cli",
@@ -3692,11 +3716,24 @@ function getBestCompletion(line, registry) {
3692
3716
  return hits.length === 1 ? hits[0].slice(trimmed.length) : "";
3693
3717
  }
3694
3718
  function resolvePrompt() {
3695
- const workspaceRoot = findWorkspaceRoot(process.cwd());
3719
+ let workspaceRoot = null;
3720
+ let current = resolve2(process.cwd());
3721
+ while (true) {
3722
+ if (isKittWorkspace(current)) {
3723
+ workspaceRoot = current;
3724
+ break;
3725
+ }
3726
+ const parent = dirname3(current);
3727
+ if (parent === current)
3728
+ break;
3729
+ current = parent;
3730
+ }
3696
3731
  if (!workspaceRoot)
3697
3732
  return `${BASE_PROMPT} > `;
3698
3733
  const manifest = readManifest(workspaceRoot);
3699
- const name = manifest?.workspace.name ?? basename(workspaceRoot);
3734
+ const name = manifest?.workspace.name;
3735
+ if (!name)
3736
+ return `${BASE_PROMPT} > `;
3700
3737
  return `${BASE_PROMPT} ${import_picocolors4.default.cyan(`[${name}]`)} > `;
3701
3738
  }
3702
3739
  async function startRepl(context) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openkitt",
3
- "version": "0.1.9",
3
+ "version": "0.2.1",
4
4
  "description": "AI-powered monorepo scaffolding CLI",
5
5
  "keywords": [
6
6
  "cli",