rvlib-shipkit 0.24.0 → 0.25.0
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/CHANGELOG.md +4 -0
- package/package.json +1 -1
- package/src/cli/cmd_Start.ts +1 -1
- package/src/start-repo.ts +23 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.25.0
|
|
4
|
+
|
|
5
|
+
- **A pre-existing EMPTY dir (or a commitless git-only husk) starts like a brand-new one.** The full-bootstrap scaffold keyed on "this run created the dir", so `mkdir foo` followed by `shipkit start foo`, or a re-run over the husk an older shipkit left, still ended in git-only plus manual next steps. The everyday-cd guard exists to protect a folder holding files, and an empty folder holds none: emptiness (junk like `.DS_Store` aside) now counts as starting intent, a `.git` with no commits counts too, and a git dir with real history stays untouched. A folder with files keeps the old behavior exactly.
|
|
6
|
+
|
|
3
7
|
## 0.24.0
|
|
4
8
|
|
|
5
9
|
- **Custom panels lead the studio drawer, and the prompt folds.** A repo's `customPanel` tabs (the tint-mask painter, a legs editor) are the working surfaces, yet they rendered LAST in the drawer tab row, behind two json diagnostics. They come first now, `asset` then `roll meta` after, and a kind with exactly one custom panel gets it as the drawer's default tab until the user picks another. The prompt textarea folds to one ellipsized line by default (click to expand, a chevron folds it back, state holds for the session), so the stage and the rolls get the height back. The drawer toggle now reads `drawer ▾`, because with a custom panel as default content a button labelled JSON opened a paint surface.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rvlib-shipkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"description": "All-in-one repo companion: ci gate (task DAG), auto-discovered health checks, release-contract fulfillness, asks queue, md-wiki tools, asset atelier, live tui",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/src/cli/cmd_Start.ts
CHANGED
|
@@ -9,7 +9,7 @@ export class StartCommand extends Command {
|
|
|
9
9
|
|
|
10
10
|
static override usage = Command.Usage({
|
|
11
11
|
category: 'Setup',
|
|
12
|
-
description: 'create (or enter) ~/dev/<name> from ANY cwd, READY to work in: ensures the dir, seeds CLAUDE.md include lines, and on a BRAND-NEW dir scaffolds a minimal package.json + src/index.ts + the rvlib-shipkit dev dep, wires shipkit (repo.config.ts via init), then runs the whole bootstrap chain: git init, first commit, PRIVATE github repo, push. A pre-existing folder
|
|
12
|
+
description: 'create (or enter) ~/dev/<name> from ANY cwd, READY to work in: ensures the dir, seeds CLAUDE.md include lines, and on a BRAND-NEW dir scaffolds a minimal package.json + src/index.ts + the rvlib-shipkit dev dep, wires shipkit (repo.config.ts via init), then runs the whole bootstrap chain: git init, first commit, PRIVATE github repo, push. A pre-existing folder counts as brand new when it is EMPTY or a commitless git husk. One holding files gets git only, never a scaffold (--github forces only the github half for it). Prints the dir on stdout so a shell alias can cd there. cwd-only sibling: `shipkit init`',
|
|
13
13
|
examples: [
|
|
14
14
|
['create or enter ~/dev/pong: dir, package.json, shipkit wiring, git, first commit, private github repo, push', 'shipkit start pong'],
|
|
15
15
|
['seed CLAUDE.md includes', "shipkit start pong --include '@~/wiki/index.md' --include '@./agent/index.md'"],
|
package/src/start-repo.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// output is the resolved dir, so a sourced shell alias can
|
|
5
5
|
// `cd "$(shipkit start <name>)"` (the one thing a child process can't do
|
|
6
6
|
// for its parent shell).
|
|
7
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'
|
|
7
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'fs'
|
|
8
8
|
import { homedir } from 'os'
|
|
9
9
|
import { join } from 'path'
|
|
10
10
|
import { ensureGitRepo, firstGhLine, IGNORE_BASELINE, isScratch, publishRepo, runner, type Run } from './git-bootstrap.ts'
|
|
@@ -35,10 +35,18 @@ export async function startRepo(name: string, opts: StartOpts = {}): Promise<num
|
|
|
35
35
|
return 2
|
|
36
36
|
}
|
|
37
37
|
const dir = join(opts.root ?? join(homedir(), 'dev'), name)
|
|
38
|
-
// this run creating the dir
|
|
39
|
-
// which is what the github half
|
|
40
|
-
// everyday cd into a folder that already
|
|
38
|
+
// this run creating the dir is the strongest signal that a repo is being
|
|
39
|
+
// STARTED, which is what the scaffold and the github half key on:
|
|
40
|
+
// `ship <name>` is also the everyday cd into a folder that already
|
|
41
|
+
// exists. A pre-existing dir with NOTHING in it carries the same intent
|
|
42
|
+
// (there are no files to protect), and so does a git-only husk with no
|
|
43
|
+
// commits (what an interrupted start leaves behind). Captured here,
|
|
44
|
+
// BEFORE the include seeding writes CLAUDE.md into the dir
|
|
41
45
|
const justCreated = !existsSync(dir)
|
|
46
|
+
const JUNK = new Set(['.DS_Store', '.localized'])
|
|
47
|
+
const entries = justCreated ? [] : readdirSync(dir).filter((e) => !JUNK.has(e))
|
|
48
|
+
const emptyDir = !justCreated && entries.length === 0
|
|
49
|
+
const gitOnlyDir = !justCreated && entries.length === 1 && entries[0] === '.git'
|
|
42
50
|
if (justCreated) {
|
|
43
51
|
mkdirSync(dir, { recursive: true })
|
|
44
52
|
console.error(`ok: created ${dir}`)
|
|
@@ -90,13 +98,17 @@ export async function startRepo(name: string, opts: StartOpts = {}): Promise<num
|
|
|
90
98
|
let wired = false
|
|
91
99
|
try { wired = await ensureGitRepo(dir, { print }) }
|
|
92
100
|
catch (e) { console.error(`WARN could not wire git in ${dir}: ${e instanceof Error ? e.message : String(e)} — the dir is still yours`) }
|
|
93
|
-
// the scaffold fires
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
-
|
|
101
|
+
// the scaffold fires for a dir this run created, a pre-existing dir
|
|
102
|
+
// that was EMPTY, or a commitless git-only husk (never --github
|
|
103
|
+
// alone: forcing the github half on a folder holding files must not
|
|
104
|
+
// write a project into it), and only where git actually wired (a
|
|
105
|
+
// subdirectory of another work tree gets nothing): the minimal
|
|
106
|
+
// package.json lands so init below has its floor and the first
|
|
107
|
+
// commit carries a working repo, not an empty husk
|
|
108
|
+
let startable = justCreated || emptyDir
|
|
109
|
+
if (!startable && gitOnlyDir && wired)
|
|
110
|
+
startable = (await runner('git', dir, 120_000)(['rev-parse', '--verify', 'HEAD'])).code !== 0
|
|
111
|
+
if (wired && startable && !existsSync(join(dir, 'package.json')) && !existsSync(join(dir, 'repo.config.ts'))) {
|
|
100
112
|
const pkg = { name, version: '0.0.0', private: true, type: 'module', scripts: {} }
|
|
101
113
|
writeFileSync(join(dir, 'package.json'), JSON.stringify(pkg, null, 4) + '\n')
|
|
102
114
|
// the first source file, so the ci gate is green from commit one:
|