codebyplan 1.13.12 → 1.13.13
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
CHANGED
|
@@ -14,7 +14,7 @@ var VERSION, PACKAGE_NAME;
|
|
|
14
14
|
var init_version = __esm({
|
|
15
15
|
"src/lib/version.ts"() {
|
|
16
16
|
"use strict";
|
|
17
|
-
VERSION = "1.13.
|
|
17
|
+
VERSION = "1.13.13";
|
|
18
18
|
PACKAGE_NAME = "codebyplan";
|
|
19
19
|
}
|
|
20
20
|
});
|
|
@@ -1281,7 +1281,11 @@ var init_template_walker = __esm({
|
|
|
1281
1281
|
"hooks/validate-structure-lengths.sh",
|
|
1282
1282
|
"hooks/validate-structure-smoke.sh",
|
|
1283
1283
|
"hooks/validate-context-usage.sh",
|
|
1284
|
-
"hooks/validate-git-commit.sh"
|
|
1284
|
+
"hooks/validate-git-commit.sh",
|
|
1285
|
+
// Advisory GATE-6 sibling-identity nudge — fires ONLY in the templates source
|
|
1286
|
+
// repo (detects packages/codebyplan-package/templates/). A no-op for consumers,
|
|
1287
|
+
// so it ships neither in hooks.json nor as a copied file.
|
|
1288
|
+
"hooks/cbp-canonical-templates-nudge.sh"
|
|
1285
1289
|
]);
|
|
1286
1290
|
}
|
|
1287
1291
|
});
|
|
@@ -5897,6 +5901,310 @@ var init_resolve_worktree2 = __esm({
|
|
|
5897
5901
|
}
|
|
5898
5902
|
});
|
|
5899
5903
|
|
|
5904
|
+
// src/cli/create-org.ts
|
|
5905
|
+
var create_org_exports = {};
|
|
5906
|
+
__export(create_org_exports, {
|
|
5907
|
+
runCreateOrg: () => runCreateOrg
|
|
5908
|
+
});
|
|
5909
|
+
import { stdin as stdin3, stdout as stdout4 } from "node:process";
|
|
5910
|
+
import { createInterface as createInterface3 } from "node:readline/promises";
|
|
5911
|
+
function deriveSlug(name) {
|
|
5912
|
+
const trimmed = name.trim();
|
|
5913
|
+
if (trimmed === "") return "";
|
|
5914
|
+
const slug = trimmed.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
5915
|
+
return slug || "org";
|
|
5916
|
+
}
|
|
5917
|
+
async function runCreateOrg() {
|
|
5918
|
+
const rl = createInterface3({ input: stdin3, output: stdout4 });
|
|
5919
|
+
console.log("\n CodeByPlan \u2014 Create Organization\n");
|
|
5920
|
+
try {
|
|
5921
|
+
const rawName = (await rl.question(" Organization name: ")).trim();
|
|
5922
|
+
if (!rawName) {
|
|
5923
|
+
console.error("\n Error: Organization name cannot be empty.\n");
|
|
5924
|
+
process.exitCode = 1;
|
|
5925
|
+
return;
|
|
5926
|
+
}
|
|
5927
|
+
const slug = deriveSlug(rawName);
|
|
5928
|
+
if (slug) {
|
|
5929
|
+
console.log(` Slug preview: ${slug}
|
|
5930
|
+
`);
|
|
5931
|
+
}
|
|
5932
|
+
let response;
|
|
5933
|
+
try {
|
|
5934
|
+
response = await apiPost("/organizations", {
|
|
5935
|
+
name: rawName
|
|
5936
|
+
});
|
|
5937
|
+
} catch (err) {
|
|
5938
|
+
if (err instanceof ApiError) {
|
|
5939
|
+
console.error(`
|
|
5940
|
+
Error: ${err.message} (HTTP ${err.status})
|
|
5941
|
+
`);
|
|
5942
|
+
} else {
|
|
5943
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
5944
|
+
console.error(`
|
|
5945
|
+
Error: ${msg}
|
|
5946
|
+
`);
|
|
5947
|
+
}
|
|
5948
|
+
process.exitCode = 1;
|
|
5949
|
+
return;
|
|
5950
|
+
}
|
|
5951
|
+
const org = response.data;
|
|
5952
|
+
console.log("\n Organization created successfully.\n");
|
|
5953
|
+
console.log(` id: ${org.id}`);
|
|
5954
|
+
console.log(` name: ${org.name}`);
|
|
5955
|
+
console.log(` slug: ${org.slug}
|
|
5956
|
+
`);
|
|
5957
|
+
} finally {
|
|
5958
|
+
rl.close();
|
|
5959
|
+
}
|
|
5960
|
+
}
|
|
5961
|
+
var init_create_org = __esm({
|
|
5962
|
+
"src/cli/create-org.ts"() {
|
|
5963
|
+
"use strict";
|
|
5964
|
+
init_api();
|
|
5965
|
+
}
|
|
5966
|
+
});
|
|
5967
|
+
|
|
5968
|
+
// src/cli/create-project.ts
|
|
5969
|
+
var create_project_exports = {};
|
|
5970
|
+
__export(create_project_exports, {
|
|
5971
|
+
runCreateProject: () => runCreateProject
|
|
5972
|
+
});
|
|
5973
|
+
import { stdin as stdin4, stdout as stdout5 } from "node:process";
|
|
5974
|
+
import { createInterface as createInterface4 } from "node:readline/promises";
|
|
5975
|
+
function deriveSlug2(name) {
|
|
5976
|
+
const trimmed = name.trim();
|
|
5977
|
+
if (trimmed === "") return "";
|
|
5978
|
+
const slug = trimmed.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
5979
|
+
return slug || "project";
|
|
5980
|
+
}
|
|
5981
|
+
async function runCreateProject() {
|
|
5982
|
+
const rl = createInterface4({ input: stdin4, output: stdout5 });
|
|
5983
|
+
console.log("\n CodeByPlan \u2014 Create Project\n");
|
|
5984
|
+
try {
|
|
5985
|
+
const orgIdFlag = (() => {
|
|
5986
|
+
const idx = process.argv.indexOf("--org-id");
|
|
5987
|
+
return idx !== -1 ? process.argv[idx + 1] ?? "" : "";
|
|
5988
|
+
})();
|
|
5989
|
+
let organizationId;
|
|
5990
|
+
if (orgIdFlag) {
|
|
5991
|
+
organizationId = orgIdFlag.trim();
|
|
5992
|
+
} else {
|
|
5993
|
+
let orgs = null;
|
|
5994
|
+
try {
|
|
5995
|
+
const resp = await apiGet("/organizations");
|
|
5996
|
+
if (resp.data && resp.data.length > 0) {
|
|
5997
|
+
orgs = resp.data;
|
|
5998
|
+
}
|
|
5999
|
+
} catch {
|
|
6000
|
+
}
|
|
6001
|
+
if (orgs && orgs.length > 0) {
|
|
6002
|
+
console.log(" Available organizations:\n");
|
|
6003
|
+
orgs.forEach((org, i) => {
|
|
6004
|
+
console.log(` ${i + 1}. ${org.name} (${org.slug}) [${org.id}]`);
|
|
6005
|
+
});
|
|
6006
|
+
console.log("");
|
|
6007
|
+
const rawChoice = (await rl.question(
|
|
6008
|
+
` Select organization (1\u2013${orgs.length}) or paste an org ID: `
|
|
6009
|
+
)).trim();
|
|
6010
|
+
const choiceNum = parseInt(rawChoice, 10);
|
|
6011
|
+
if (!isNaN(choiceNum) && choiceNum >= 1 && choiceNum <= orgs.length) {
|
|
6012
|
+
organizationId = orgs[choiceNum - 1].id;
|
|
6013
|
+
} else if (rawChoice) {
|
|
6014
|
+
organizationId = rawChoice;
|
|
6015
|
+
} else {
|
|
6016
|
+
console.error("\n Error: Organization selection cannot be empty.\n");
|
|
6017
|
+
process.exitCode = 1;
|
|
6018
|
+
return;
|
|
6019
|
+
}
|
|
6020
|
+
} else {
|
|
6021
|
+
const rawOrgId = (await rl.question(" Organization ID: ")).trim();
|
|
6022
|
+
if (!rawOrgId) {
|
|
6023
|
+
console.error("\n Error: Organization ID cannot be empty.\n");
|
|
6024
|
+
process.exitCode = 1;
|
|
6025
|
+
return;
|
|
6026
|
+
}
|
|
6027
|
+
organizationId = rawOrgId;
|
|
6028
|
+
}
|
|
6029
|
+
}
|
|
6030
|
+
const rawName = (await rl.question(" Project name: ")).trim();
|
|
6031
|
+
if (!rawName) {
|
|
6032
|
+
console.error("\n Error: Project name cannot be empty.\n");
|
|
6033
|
+
process.exitCode = 1;
|
|
6034
|
+
return;
|
|
6035
|
+
}
|
|
6036
|
+
const slug = deriveSlug2(rawName);
|
|
6037
|
+
if (slug) {
|
|
6038
|
+
console.log(` Slug preview: ${slug}
|
|
6039
|
+
`);
|
|
6040
|
+
}
|
|
6041
|
+
let response;
|
|
6042
|
+
try {
|
|
6043
|
+
response = await apiPost("/projects", {
|
|
6044
|
+
organization_id: organizationId,
|
|
6045
|
+
name: rawName
|
|
6046
|
+
});
|
|
6047
|
+
} catch (err) {
|
|
6048
|
+
if (err instanceof ApiError) {
|
|
6049
|
+
console.error(`
|
|
6050
|
+
Error: ${err.message} (HTTP ${err.status})
|
|
6051
|
+
`);
|
|
6052
|
+
} else {
|
|
6053
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6054
|
+
console.error(`
|
|
6055
|
+
Error: ${msg}
|
|
6056
|
+
`);
|
|
6057
|
+
}
|
|
6058
|
+
process.exitCode = 1;
|
|
6059
|
+
return;
|
|
6060
|
+
}
|
|
6061
|
+
const project = response.data;
|
|
6062
|
+
console.log("\n Project created successfully.\n");
|
|
6063
|
+
console.log(` id: ${project.id}`);
|
|
6064
|
+
console.log(` name: ${project.name}`);
|
|
6065
|
+
console.log(` slug: ${project.slug}
|
|
6066
|
+
`);
|
|
6067
|
+
} finally {
|
|
6068
|
+
rl.close();
|
|
6069
|
+
}
|
|
6070
|
+
}
|
|
6071
|
+
var init_create_project = __esm({
|
|
6072
|
+
"src/cli/create-project.ts"() {
|
|
6073
|
+
"use strict";
|
|
6074
|
+
init_api();
|
|
6075
|
+
}
|
|
6076
|
+
});
|
|
6077
|
+
|
|
6078
|
+
// src/cli/create-repo.ts
|
|
6079
|
+
var create_repo_exports = {};
|
|
6080
|
+
__export(create_repo_exports, {
|
|
6081
|
+
runCreateRepo: () => runCreateRepo
|
|
6082
|
+
});
|
|
6083
|
+
import { stdin as stdin5, stdout as stdout6 } from "node:process";
|
|
6084
|
+
import { createInterface as createInterface5 } from "node:readline/promises";
|
|
6085
|
+
async function runCreateRepo() {
|
|
6086
|
+
const rl = createInterface5({ input: stdin5, output: stdout6 });
|
|
6087
|
+
console.log("\n CodeByPlan \u2014 Create Repository\n");
|
|
6088
|
+
try {
|
|
6089
|
+
const projectIdFlag = (() => {
|
|
6090
|
+
const idx = process.argv.indexOf("--project-id");
|
|
6091
|
+
return idx !== -1 ? process.argv[idx + 1] ?? "" : "";
|
|
6092
|
+
})();
|
|
6093
|
+
let projectId;
|
|
6094
|
+
if (projectIdFlag) {
|
|
6095
|
+
const trimmedFlag = projectIdFlag.trim();
|
|
6096
|
+
if (!UUID_RE.test(trimmedFlag)) {
|
|
6097
|
+
console.error("\n Error: Project ID must be a valid UUID.\n");
|
|
6098
|
+
process.exitCode = 1;
|
|
6099
|
+
return;
|
|
6100
|
+
}
|
|
6101
|
+
projectId = trimmedFlag;
|
|
6102
|
+
} else {
|
|
6103
|
+
let projects = null;
|
|
6104
|
+
try {
|
|
6105
|
+
const resp = await apiGet("/projects");
|
|
6106
|
+
if (resp.data && resp.data.length > 0) {
|
|
6107
|
+
projects = resp.data;
|
|
6108
|
+
}
|
|
6109
|
+
} catch {
|
|
6110
|
+
}
|
|
6111
|
+
if (projects && projects.length > 0) {
|
|
6112
|
+
console.log(" Available projects:\n");
|
|
6113
|
+
projects.forEach((proj, i) => {
|
|
6114
|
+
console.log(
|
|
6115
|
+
` ${i + 1}. ${proj.name} (${proj.slug}) [${proj.id}]`
|
|
6116
|
+
);
|
|
6117
|
+
});
|
|
6118
|
+
console.log("");
|
|
6119
|
+
const rawChoice = (await rl.question(
|
|
6120
|
+
` Select project (1\u2013${projects.length}) or paste a project ID: `
|
|
6121
|
+
)).trim();
|
|
6122
|
+
const choiceNum = parseInt(rawChoice, 10);
|
|
6123
|
+
if (!isNaN(choiceNum) && choiceNum >= 1 && choiceNum <= projects.length) {
|
|
6124
|
+
projectId = projects[choiceNum - 1].id;
|
|
6125
|
+
} else if (rawChoice) {
|
|
6126
|
+
if (!UUID_RE.test(rawChoice)) {
|
|
6127
|
+
console.error("\n Error: Project ID must be a valid UUID.\n");
|
|
6128
|
+
process.exitCode = 1;
|
|
6129
|
+
return;
|
|
6130
|
+
}
|
|
6131
|
+
projectId = rawChoice;
|
|
6132
|
+
} else {
|
|
6133
|
+
console.error("\n Error: Project selection cannot be empty.\n");
|
|
6134
|
+
process.exitCode = 1;
|
|
6135
|
+
return;
|
|
6136
|
+
}
|
|
6137
|
+
} else {
|
|
6138
|
+
const rawProjectId = (await rl.question(" Project ID: ")).trim();
|
|
6139
|
+
if (!rawProjectId) {
|
|
6140
|
+
console.error("\n Error: Project ID cannot be empty.\n");
|
|
6141
|
+
process.exitCode = 1;
|
|
6142
|
+
return;
|
|
6143
|
+
}
|
|
6144
|
+
if (!UUID_RE.test(rawProjectId)) {
|
|
6145
|
+
console.error("\n Error: Project ID must be a valid UUID.\n");
|
|
6146
|
+
process.exitCode = 1;
|
|
6147
|
+
return;
|
|
6148
|
+
}
|
|
6149
|
+
projectId = rawProjectId;
|
|
6150
|
+
}
|
|
6151
|
+
}
|
|
6152
|
+
const rawName = (await rl.question(" Repository name: ")).trim();
|
|
6153
|
+
if (!rawName) {
|
|
6154
|
+
console.error("\n Error: Repository name cannot be empty.\n");
|
|
6155
|
+
process.exitCode = 1;
|
|
6156
|
+
return;
|
|
6157
|
+
}
|
|
6158
|
+
const rawPath = (await rl.question(" Local path (optional, press Enter to skip): ")).trim();
|
|
6159
|
+
const rawBranch = (await rl.question(
|
|
6160
|
+
" Default git branch (optional, press Enter for 'main'): "
|
|
6161
|
+
)).trim();
|
|
6162
|
+
const git_branch = rawBranch || "main";
|
|
6163
|
+
let response;
|
|
6164
|
+
try {
|
|
6165
|
+
response = await apiPost("/repos", {
|
|
6166
|
+
project_id: projectId,
|
|
6167
|
+
name: rawName,
|
|
6168
|
+
...rawPath ? { path: rawPath } : {},
|
|
6169
|
+
git_branch
|
|
6170
|
+
});
|
|
6171
|
+
} catch (err) {
|
|
6172
|
+
if (err instanceof ApiError) {
|
|
6173
|
+
console.error(`
|
|
6174
|
+
Error: ${err.message} (HTTP ${err.status})
|
|
6175
|
+
`);
|
|
6176
|
+
} else {
|
|
6177
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6178
|
+
console.error(`
|
|
6179
|
+
Error: ${msg}
|
|
6180
|
+
`);
|
|
6181
|
+
}
|
|
6182
|
+
process.exitCode = 1;
|
|
6183
|
+
return;
|
|
6184
|
+
}
|
|
6185
|
+
const repo = response.data;
|
|
6186
|
+
console.log("\n Repository created successfully.\n");
|
|
6187
|
+
console.log(` id: ${repo.id}`);
|
|
6188
|
+
console.log(` name: ${repo.name}`);
|
|
6189
|
+
console.log(` git_branch: ${repo.git_branch ?? git_branch}`);
|
|
6190
|
+
console.log(
|
|
6191
|
+
`
|
|
6192
|
+
Tip: run \`codebyplan setup\` from the repo directory to link it.
|
|
6193
|
+
`
|
|
6194
|
+
);
|
|
6195
|
+
} finally {
|
|
6196
|
+
rl.close();
|
|
6197
|
+
}
|
|
6198
|
+
}
|
|
6199
|
+
var UUID_RE;
|
|
6200
|
+
var init_create_repo = __esm({
|
|
6201
|
+
"src/cli/create-repo.ts"() {
|
|
6202
|
+
"use strict";
|
|
6203
|
+
init_api();
|
|
6204
|
+
UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
6205
|
+
}
|
|
6206
|
+
});
|
|
6207
|
+
|
|
5900
6208
|
// src/cli/version-status.ts
|
|
5901
6209
|
var version_status_exports = {};
|
|
5902
6210
|
__export(version_status_exports, {
|
|
@@ -7875,6 +8183,21 @@ void (async () => {
|
|
|
7875
8183
|
await runResolveWorktree2();
|
|
7876
8184
|
process.exit(0);
|
|
7877
8185
|
}
|
|
8186
|
+
if (arg === "create-org") {
|
|
8187
|
+
const { runCreateOrg: runCreateOrg2 } = await Promise.resolve().then(() => (init_create_org(), create_org_exports));
|
|
8188
|
+
await runCreateOrg2();
|
|
8189
|
+
process.exit(0);
|
|
8190
|
+
}
|
|
8191
|
+
if (arg === "create-project") {
|
|
8192
|
+
const { runCreateProject: runCreateProject2 } = await Promise.resolve().then(() => (init_create_project(), create_project_exports));
|
|
8193
|
+
await runCreateProject2();
|
|
8194
|
+
process.exit(0);
|
|
8195
|
+
}
|
|
8196
|
+
if (arg === "create-repo") {
|
|
8197
|
+
const { runCreateRepo: runCreateRepo2 } = await Promise.resolve().then(() => (init_create_repo(), create_repo_exports));
|
|
8198
|
+
await runCreateRepo2();
|
|
8199
|
+
process.exit(0);
|
|
8200
|
+
}
|
|
7878
8201
|
if (arg === "version-status") {
|
|
7879
8202
|
const { runVersionStatus: runVersionStatus2 } = await Promise.resolve().then(() => (init_version_status(), version_status_exports));
|
|
7880
8203
|
await runVersionStatus2();
|
|
@@ -7970,6 +8293,9 @@ void (async () => {
|
|
|
7970
8293
|
codebyplan logout Clear cached OAuth tokens
|
|
7971
8294
|
codebyplan whoami Show currently authenticated identity
|
|
7972
8295
|
codebyplan upgrade-auth Migrate legacy x-api-key MCP config to OAuth
|
|
8296
|
+
codebyplan create-org Create a new organization (interactive prompt)
|
|
8297
|
+
codebyplan create-project Create a new project within an organization (interactive prompt)
|
|
8298
|
+
codebyplan create-repo Create a new repository within a project (interactive prompt)
|
|
7973
8299
|
codebyplan config Sync repo config from DB to .codebyplan/ files
|
|
7974
8300
|
codebyplan ports Verify port allocations against local package.json scripts
|
|
7975
8301
|
codebyplan tech-stack Detect and sync tech stack dependencies
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codebyplan",
|
|
3
|
-
"version": "1.13.
|
|
3
|
+
"version": "1.13.13",
|
|
4
4
|
"description": "CLI for CodeByPlan — AI-powered development planning and tracking",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -61,6 +61,6 @@
|
|
|
61
61
|
"prettier": "^3.8.1",
|
|
62
62
|
"typescript": "^5",
|
|
63
63
|
"typescript-eslint": "^8.20.0",
|
|
64
|
-
"vitest": "^4.
|
|
64
|
+
"vitest": "^4.1.2"
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -58,6 +58,8 @@
|
|
|
58
58
|
"mcp__codebyplan__create_launch",
|
|
59
59
|
"mcp__codebyplan__update_launch",
|
|
60
60
|
"mcp__codebyplan__delete_launch",
|
|
61
|
+
"mcp__codebyplan__create_organization",
|
|
62
|
+
"mcp__codebyplan__create_project",
|
|
61
63
|
"mcp__codebyplan__create_repo",
|
|
62
64
|
"mcp__codebyplan__delete_session_log",
|
|
63
65
|
"mcp__codebyplan__delete_worktree",
|
|
@@ -67,6 +69,12 @@
|
|
|
67
69
|
"mcp__codebyplan__release_assignment",
|
|
68
70
|
"Bash(codebyplan setup:*)",
|
|
69
71
|
"Bash(npx codebyplan setup:*)",
|
|
72
|
+
"Bash(codebyplan create-org:*)",
|
|
73
|
+
"Bash(npx codebyplan create-org:*)",
|
|
74
|
+
"Bash(codebyplan create-project:*)",
|
|
75
|
+
"Bash(npx codebyplan create-project:*)",
|
|
76
|
+
"Bash(codebyplan create-repo:*)",
|
|
77
|
+
"Bash(npx codebyplan create-repo:*)",
|
|
70
78
|
"Bash(codebyplan login:*)",
|
|
71
79
|
"Bash(npx codebyplan login:*)",
|
|
72
80
|
"Bash(codebyplan logout:*)",
|