openkitt 0.2.0 → 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.
- package/dist/cli.js +163 -93
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2800,9 +2800,9 @@ var {
|
|
|
2800
2800
|
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
2801
2801
|
import { createInterface, emitKeypressEvents } from "node:readline";
|
|
2802
2802
|
import { stdin as input, stdout as output } from "node:process";
|
|
2803
|
-
import { existsSync as
|
|
2804
|
-
import { homedir as
|
|
2805
|
-
import { join as
|
|
2803
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5, realpathSync } from "node:fs";
|
|
2804
|
+
import { homedir as homedir3 } from "node:os";
|
|
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
|
|
3132
|
-
mkdirSync as
|
|
3261
|
+
existsSync as existsSync5,
|
|
3262
|
+
mkdirSync as mkdirSync4,
|
|
3133
3263
|
readdirSync,
|
|
3134
|
-
readFileSync as
|
|
3264
|
+
readFileSync as readFileSync5,
|
|
3135
3265
|
rmSync as rmSync2,
|
|
3136
3266
|
statSync as statSync3,
|
|
3137
|
-
writeFileSync as
|
|
3267
|
+
writeFileSync as writeFileSync4
|
|
3138
3268
|
} from "node:fs";
|
|
3139
|
-
import { dirname, join as
|
|
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
|
|
3145
|
-
mkdirSync as
|
|
3274
|
+
existsSync as existsSync4,
|
|
3275
|
+
mkdirSync as mkdirSync3,
|
|
3146
3276
|
renameSync as renameSync2,
|
|
3147
3277
|
rmSync,
|
|
3148
3278
|
statSync as statSync2,
|
|
3149
|
-
writeFileSync as
|
|
3279
|
+
writeFileSync as writeFileSync3
|
|
3150
3280
|
} from "node:fs";
|
|
3151
|
-
import { join as
|
|
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 (
|
|
3292
|
+
if (existsSync4(auditDir)) {
|
|
3163
3293
|
return;
|
|
3164
3294
|
}
|
|
3165
|
-
|
|
3295
|
+
mkdirSync3(auditDir, { recursive: true, mode: 448 });
|
|
3166
3296
|
}
|
|
3167
3297
|
function rotateLogIfNeeded(logPath, log1Path, log2Path) {
|
|
3168
|
-
if (!
|
|
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 (
|
|
3305
|
+
if (existsSync4(log2Path)) {
|
|
3176
3306
|
rmSync(log2Path, { force: true });
|
|
3177
3307
|
}
|
|
3178
|
-
if (
|
|
3308
|
+
if (existsSync4(log1Path)) {
|
|
3179
3309
|
renameSync2(log1Path, log2Path);
|
|
3180
3310
|
}
|
|
3181
3311
|
renameSync2(logPath, log1Path);
|
|
3182
|
-
|
|
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 =
|
|
3194
|
-
const logPath =
|
|
3195
|
-
const log1Path =
|
|
3196
|
-
const log2Path =
|
|
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
|
|
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 (
|
|
3375
|
+
if (existsSync5(stagingDir)) {
|
|
3246
3376
|
rmSync2(stagingDir, { recursive: true, force: true });
|
|
3247
3377
|
}
|
|
3248
|
-
|
|
3249
|
-
logger.staged(
|
|
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,70 +3412,10 @@ function registerCleanupHandlers() {
|
|
|
3282
3412
|
handleCleanupSignal("SIGTERM");
|
|
3283
3413
|
});
|
|
3284
3414
|
}
|
|
3285
|
-
|
|
3286
|
-
// src/manifest/reader.ts
|
|
3287
|
-
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
|
|
3288
|
-
import { join as join4, dirname as dirname2, resolve } from "node:path";
|
|
3289
|
-
function isObjectRecord(value) {
|
|
3290
|
-
return typeof value === "object" && value !== null;
|
|
3291
|
-
}
|
|
3292
|
-
function isValidWorkspaceManifest(value) {
|
|
3293
|
-
if (!isObjectRecord(value)) {
|
|
3294
|
-
return false;
|
|
3295
|
-
}
|
|
3296
|
-
if (typeof value.version !== "string") {
|
|
3297
|
-
return false;
|
|
3298
|
-
}
|
|
3299
|
-
if (!isObjectRecord(value.workspace)) {
|
|
3300
|
-
return false;
|
|
3301
|
-
}
|
|
3302
|
-
if (typeof value.workspace.name !== "string") {
|
|
3303
|
-
return false;
|
|
3304
|
-
}
|
|
3305
|
-
const packageManager = value.workspace.packageManager;
|
|
3306
|
-
if (packageManager !== "bun" && packageManager !== "npm" && packageManager !== "pnpm" && packageManager !== "yarn") {
|
|
3307
|
-
return false;
|
|
3308
|
-
}
|
|
3309
|
-
if (!isObjectRecord(value.apps)) {
|
|
3310
|
-
return false;
|
|
3311
|
-
}
|
|
3312
|
-
if (!isObjectRecord(value.packages)) {
|
|
3313
|
-
return false;
|
|
3314
|
-
}
|
|
3315
|
-
if (!isObjectRecord(value.settings)) {
|
|
3316
|
-
return false;
|
|
3317
|
-
}
|
|
3318
|
-
return true;
|
|
3319
|
-
}
|
|
3320
|
-
function getManifestPath(workspaceDir) {
|
|
3321
|
-
return join4(workspaceDir, ".kitt", "manifest.json");
|
|
3322
|
-
}
|
|
3323
|
-
function isKittWorkspace(dir) {
|
|
3324
|
-
return existsSync4(getManifestPath(dir));
|
|
3325
|
-
}
|
|
3326
|
-
function readManifest(workspaceDir) {
|
|
3327
|
-
const manifestPath = getManifestPath(workspaceDir);
|
|
3328
|
-
if (!existsSync4(manifestPath)) {
|
|
3329
|
-
return null;
|
|
3330
|
-
}
|
|
3331
|
-
try {
|
|
3332
|
-
const raw = readFileSync4(manifestPath, "utf-8").trim();
|
|
3333
|
-
if (raw.length === 0) {
|
|
3334
|
-
return null;
|
|
3335
|
-
}
|
|
3336
|
-
const parsed = JSON.parse(raw);
|
|
3337
|
-
if (!isValidWorkspaceManifest(parsed)) {
|
|
3338
|
-
return null;
|
|
3339
|
-
}
|
|
3340
|
-
return parsed;
|
|
3341
|
-
} catch {
|
|
3342
|
-
return null;
|
|
3343
|
-
}
|
|
3344
|
-
}
|
|
3345
3415
|
// package.json
|
|
3346
3416
|
var package_default = {
|
|
3347
3417
|
name: "openkitt",
|
|
3348
|
-
version: "0.2.
|
|
3418
|
+
version: "0.2.1",
|
|
3349
3419
|
description: "AI-powered monorepo scaffolding CLI",
|
|
3350
3420
|
keywords: [
|
|
3351
3421
|
"cli",
|
|
@@ -3418,8 +3488,8 @@ var STATE_CHANGING_COMMANDS = new Set([
|
|
|
3418
3488
|
"domain",
|
|
3419
3489
|
"publish"
|
|
3420
3490
|
]);
|
|
3421
|
-
var KITT_DIR2 =
|
|
3422
|
-
var UPDATE_CHECK_FILE =
|
|
3491
|
+
var KITT_DIR2 = join6(homedir3(), ".kitt");
|
|
3492
|
+
var UPDATE_CHECK_FILE = join6(KITT_DIR2, "update-check.json");
|
|
3423
3493
|
var commandRegistry = {
|
|
3424
3494
|
init: { modulePath: "./commands/init.js" },
|
|
3425
3495
|
create: { modulePath: "./commands/create.js" },
|
|
@@ -3500,11 +3570,11 @@ function isVersionNewer(latest, current) {
|
|
|
3500
3570
|
return false;
|
|
3501
3571
|
}
|
|
3502
3572
|
function hasFreshUpdateCache(now) {
|
|
3503
|
-
if (!
|
|
3573
|
+
if (!existsSync6(UPDATE_CHECK_FILE)) {
|
|
3504
3574
|
return false;
|
|
3505
3575
|
}
|
|
3506
3576
|
try {
|
|
3507
|
-
const rawCache =
|
|
3577
|
+
const rawCache = readFileSync6(UPDATE_CHECK_FILE, "utf-8").trim();
|
|
3508
3578
|
if (rawCache.length === 0) {
|
|
3509
3579
|
return false;
|
|
3510
3580
|
}
|
|
@@ -3522,12 +3592,12 @@ function hasFreshUpdateCache(now) {
|
|
|
3522
3592
|
}
|
|
3523
3593
|
}
|
|
3524
3594
|
function writeUpdateCache(now, latestVersion) {
|
|
3525
|
-
|
|
3595
|
+
mkdirSync5(KITT_DIR2, { recursive: true });
|
|
3526
3596
|
const payload = {
|
|
3527
3597
|
checkedAt: now.toISOString(),
|
|
3528
3598
|
latestVersion
|
|
3529
3599
|
};
|
|
3530
|
-
|
|
3600
|
+
writeFileSync5(UPDATE_CHECK_FILE, `${JSON.stringify(payload, null, 2)}
|
|
3531
3601
|
`, "utf-8");
|
|
3532
3602
|
}
|
|
3533
3603
|
async function checkForUpdates(context) {
|