insta 0.0.16 → 0.0.18
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/commands/project.js +17 -17
- package/dist/config.js +4 -1
- package/package.json +1 -1
package/dist/commands/project.js
CHANGED
|
@@ -5,21 +5,13 @@ import { info, die, printJson, handleApproval, renderNextActions } from '../util
|
|
|
5
5
|
import { installObserve } from '../observe/install.js';
|
|
6
6
|
import { installSkills } from '../ensure-skills.js';
|
|
7
7
|
// Generic directory names that make a useless project name ("projects", "~", "tmp", …). When the
|
|
8
|
-
// cwd basename is one of these we
|
|
8
|
+
// cwd basename is one of these we DON'T invent a name — we guide the user to name it (or let their
|
|
9
|
+
// skill-equipped agent do it), rather than provisioning real resources under a junk name.
|
|
9
10
|
const GENERIC_DIRS = new Set([
|
|
10
11
|
'projects', 'project', 'home', 'tmp', 'temp', 'desktop', 'documents', 'downloads',
|
|
11
12
|
'src', 'source', 'code', 'dev', 'work', 'workspace', 'repos', 'repo', 'git',
|
|
12
13
|
'app', 'apps', 'users', 'user', 'bin', 'new', 'test', 'tests',
|
|
13
14
|
]);
|
|
14
|
-
const ADJ = ['swift', 'brave', 'calm', 'bright', 'bold', 'quiet', 'warm', 'keen', 'wise',
|
|
15
|
-
'lucky', 'sunny', 'cosmic', 'gentle', 'rapid', 'vivid', 'amber', 'crisp', 'noble'];
|
|
16
|
-
const NOUN = ['otter', 'falcon', 'maple', 'river', 'harbor', 'meadow', 'comet', 'cedar', 'lark',
|
|
17
|
-
'delta', 'summit', 'ember', 'willow', 'pixel', 'forge', 'harbor', 'atlas', 'quartz'];
|
|
18
|
-
/** A friendly auto-generated name like `swift-meadow-482` (Vercel/Render style). */
|
|
19
|
-
export function generateProjectName(rand = Math.random) {
|
|
20
|
-
const pick = (a) => a[Math.floor(rand() * a.length)];
|
|
21
|
-
return `${pick(ADJ)}-${pick(NOUN)}-${100 + Math.floor(rand() * 900)}`;
|
|
22
|
-
}
|
|
23
15
|
// Best-effort: wire the credential-audit hook into the project (no-op if assets aren't built).
|
|
24
16
|
function tryInstallObserve() {
|
|
25
17
|
try {
|
|
@@ -41,23 +33,31 @@ async function resolveOrg(api, given) {
|
|
|
41
33
|
export function slugifyName(raw) {
|
|
42
34
|
return raw.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 40);
|
|
43
35
|
}
|
|
44
|
-
/** Name resolution
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
|
|
36
|
+
/** Name resolution — NEVER prompts (a paste-and-run one-liner must not block on input). Returns
|
|
37
|
+
* the name to create, or `null` meaning "no sensible name; guide the user instead of inventing
|
|
38
|
+
* one". Explicit arg wins; else the cwd basename when it's a real project-dir name; else null
|
|
39
|
+
* (generic dir like ~/projects or /tmp, or the home dir itself). Agents pass a name via the skill,
|
|
40
|
+
* so null is only reached when a human runs bare `insta project create` somewhere generic. */
|
|
41
|
+
export function resolveProjectName(nameArg, cwd = process.cwd()) {
|
|
49
42
|
if (nameArg)
|
|
50
43
|
return slugifyName(nameArg);
|
|
51
44
|
const base = slugifyName(cwd.split('/').filter(Boolean).pop() ?? '');
|
|
52
45
|
const home = slugifyName(homedir().split('/').filter(Boolean).pop() ?? '');
|
|
53
46
|
if (base && base !== home && !GENERIC_DIRS.has(base))
|
|
54
47
|
return base;
|
|
55
|
-
return
|
|
48
|
+
return null;
|
|
56
49
|
}
|
|
57
50
|
export async function projectCreate(name, opts) {
|
|
51
|
+
const resolved = resolveProjectName(name, process.cwd());
|
|
52
|
+
if (!resolved) {
|
|
53
|
+
// No name given and the cwd name is generic — don't provision resources under a junk name.
|
|
54
|
+
// Guide instead (no hang, no error): name it explicitly, or just ask the skill-equipped agent.
|
|
55
|
+
info('name your project: insta project create <name>');
|
|
56
|
+
info(' (or just ask your coding agent — it has the insta skill and will do this for you)');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
58
59
|
const api = await ApiClient.load();
|
|
59
60
|
const orgId = await resolveOrg(api, opts.org);
|
|
60
|
-
const resolved = await resolveProjectName(name, process.cwd());
|
|
61
61
|
const out = await api.request('POST', `/orgs/${orgId}/projects`, { name: resolved });
|
|
62
62
|
await writeProject({ projectId: out.project.id, orgId, branch: out.defaultBranch.name });
|
|
63
63
|
info(`created project ${out.project.id} (${resolved})`);
|
package/dist/config.js
CHANGED
|
@@ -6,7 +6,10 @@ const GLOBAL_DIR = join(homedir(), '.insta');
|
|
|
6
6
|
const GLOBAL_FILE = join(GLOBAL_DIR, 'config.json');
|
|
7
7
|
const PROJECT_DIR = '.insta';
|
|
8
8
|
const PROJECT_FILE = 'project.json';
|
|
9
|
-
|
|
9
|
+
// The cloud API default. Uses the instacloud.com brand domain (matches the agents.instacloud.com
|
|
10
|
+
// onboarding), NOT the legacy beta-api.insta.insforge.dev host — same backend, branded domain.
|
|
11
|
+
// Only affects fresh installs: a persisted apiUrl (from a prior login) or INSTA_API_URL wins below.
|
|
12
|
+
const DEFAULT_API = 'https://api.instacloud.com';
|
|
10
13
|
export async function readGlobal() {
|
|
11
14
|
// INSTA_API_URL overrides the persisted apiUrl, not just the default — otherwise the
|
|
12
15
|
// env var is silently ignored as soon as any login has written a config file.
|