@ajaykumarnpm/talea 0.5.0 → 0.6.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 CHANGED
@@ -4,6 +4,11 @@ All notable changes to this project are recorded here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the versions follow
5
5
  [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.6.0] - 2026-09-22
8
+
9
+ ### Breaking
10
+ - `talea pick <repo>` keeps one repo; `talea update` upgrades the CLI
11
+
7
12
  ## [0.5.0] - 2026-09-22
8
13
 
9
14
  ### Added
package/README.md CHANGED
@@ -66,6 +66,7 @@ talea sync # clone the new, fast-forward the rest
66
66
  talea status # branch, clean/dirty, ahead/behind, in one table
67
67
  talea add some-repo # keep one more on this machine, and clone it now
68
68
  talea select # reopen the checklist and change the whole list
69
+ talea pick some-repo # keep that one — an unknown name opens the checklist
69
70
  cd $(talea where eklavya)
70
71
  ```
71
72
 
@@ -167,7 +168,7 @@ Treat the id like a bookmark you would not paste into a public channel.
167
168
  | `talea clone` | clone only — never fetches or merges |
168
169
  | `talea adopt` | move checkouts you already have into place |
169
170
  | `talea status` | branch, clean/dirty, ahead/behind |
170
- | `talea select` | reopen the checklist — what this machine keeps |
171
+ | `talea select` | reopen the checklist — `talea pick <repo>` for one |
171
172
  | `talea add` / `talea rm` | change that one repo at a time |
172
173
  | `talea where <repo>` | print a repo's path, for `cd $( )` |
173
174
  | `talea list` | the catalogue |
@@ -176,7 +177,7 @@ Treat the id like a bookmark you would not paste into a public channel.
176
177
  | `talea manifest push/pull` | move the catalogue between machines |
177
178
  | `talea skill` | install the skill that lets your coding agent drive talea |
178
179
  | `talea doctor` | check this machine can do the work |
179
- | `talea upgrade` | update the CLI itself |
180
+ | `talea upgrade` | update the CLI itself (also `talea update`) |
180
181
 
181
182
  Every one of them takes `-g <group>` and `-r <repo>` to narrow the run, and
182
183
  `--help` for its own examples.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ajaykumarnpm/talea",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "One folder structure for every machine. Clone, adopt and sync your GitHub repos from a manifest you own.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -117,11 +117,17 @@ and nothing in talea will do it for them.
117
117
  talea add some-repo # keep one more here, and clone it now
118
118
  talea rm some-repo # stop keeping it — the checkout stays exactly where it is
119
119
  talea select # reopen the whole checklist, interactively
120
+ talea pick some-repo # = add when the name is exact; otherwise the checklist
120
121
  ```
121
122
 
122
123
  `talea select` needs a terminal. In a non-interactive session it prints a
123
124
  summary instead of hanging, so prefer `add` and `rm` when acting on the
124
125
  developer's behalf and leave `select` as something to suggest they run.
126
+ `pick <name>` falls back to that same checklist on a typo, so an agent uses
127
+ `add`, which fails loudly instead.
128
+
129
+ `talea update` reinstalls the CLI (it is `upgrade`), not `sync`. Never run it
130
+ to refresh repos.
125
131
 
126
132
  `rm` does **not** delete the checkout. Say that plainly when you run it, or it
127
133
  reads like data loss.
package/src/cli.js CHANGED
@@ -52,7 +52,6 @@ const ALIASES = {
52
52
  setup: 'init',
53
53
  bootstrap: 'init',
54
54
  pull: 'sync',
55
- update: 'sync',
56
55
  refresh: 'discover',
57
56
  pick: 'select',
58
57
  choose: 'select',
@@ -63,6 +62,7 @@ const ALIASES = {
63
62
  run: 'exec',
64
63
  skills: 'skill',
65
64
  remove: 'rm',
65
+ update: 'upgrade',
66
66
  'self-update': 'upgrade',
67
67
  };
68
68
 
@@ -110,7 +110,7 @@ ${c.bold('Commands')}
110
110
  ${c.cyan('clone')} clone only — never fetches or merges
111
111
  ${c.cyan('adopt')} move repos you already have into the right place
112
112
  ${c.cyan('status')} one table: branch, clean/dirty, ahead/behind
113
- ${c.cyan('select')} reopen the checklist — what this machine keeps
113
+ ${c.cyan('select')} reopen the checklist — or ${c.dim('talea pick <repo>')} for one
114
114
  ${c.cyan('add')} keep another repo on this machine (${c.dim('rm')} to drop one)
115
115
  ${c.cyan('where')} print a repo's path — ${c.dim('cd $(talea where eklavya)')}
116
116
  ${c.cyan('list')} show the catalogue
@@ -34,12 +34,17 @@ Options
34
34
  -j, --jobs <n> parallel clones
35
35
  `;
36
36
 
37
- /** Resolve `name` or `owner/name` against the catalogue, or exit saying why. */
38
- export function resolve(manifest, name) {
37
+ /** Every catalogue entry `name` or `owner/name` could mean, ignoring case. */
38
+ export function lookup(manifest, name) {
39
39
  const wanted = String(name).toLowerCase();
40
- const matches = manifest.repos.filter(
40
+ return manifest.repos.filter(
41
41
  (r) => r.name.toLowerCase() === wanted || `${r.owner}/${r.name}`.toLowerCase() === wanted,
42
42
  );
43
+ }
44
+
45
+ /** Resolve `name` or `owner/name` against the catalogue, or exit saying why. */
46
+ export function resolve(manifest, name) {
47
+ const matches = lookup(manifest, name);
43
48
 
44
49
  if (!matches.length) {
45
50
  fail(`No repo called "${name}" in the catalogue.`);
@@ -9,9 +9,10 @@
9
9
  // because `clone` and `sync` ask the same question, and the cloning is
10
10
  // `clone.run`, re-entered after the new selection is on disk.
11
11
 
12
- import { c, fail, heading, ok, plain, skip } from '../log.js';
12
+ import { c, fail, heading, ok, plain, skip, warn } from '../log.js';
13
13
  import { chooseRepos } from '../select.js';
14
14
  import { machineRepos, requireCatalogue, requireWorkspace } from '../workspace.js';
15
+ import * as add from './add.js';
15
16
  import * as clone from './clone.js';
16
17
 
17
18
  export const help = `
@@ -19,6 +20,8 @@ ${c.bold('talea select')} — change what this machine keeps
19
20
 
20
21
  ${c.dim('talea select')} reopen the checklist, then clone what is newly ticked
21
22
  ${c.dim('talea select --no-clone')} change the list only, fill it in later
23
+ ${c.dim('talea pick PiDom')} keep that one repo and clone it — or, if no repo
24
+ has that name, open the checklist instead
22
25
 
23
26
  The checklist opens with the current selection ticked. Space toggles, Enter
24
27
  saves, Esc cancels and changes nothing. Everything in the catalogue is listed,
@@ -29,7 +32,10 @@ It writes ${c.dim('.talea.json')}, which never leaves this machine, so no other
29
32
  selection changes. Unticking a repo takes it off the list and leaves the
30
33
  checkout exactly where it is; deleting it is your call.
31
34
 
32
- For one repo, ${c.dim('talea add <repo>')} and ${c.dim('talea rm <repo>')} skip the checklist.
35
+ A name that matches exactly one repo (case does not matter, ${c.dim('owner/name')} works)
36
+ is ${c.dim('talea add <repo>')}. A name that matches none, or two owners' repos, opens the
37
+ checklist, because a typo should land you in the list rather than nowhere.
38
+ ${c.dim('talea rm <repo>')} takes one off.
33
39
 
34
40
  Options
35
41
  --no-clone save the selection, clone nothing
@@ -37,6 +43,11 @@ Options
37
43
  -j, --jobs <n> parallel clones
38
44
  `;
39
45
 
46
+ /** The names that do not pin down exactly one repo — empty means every one does. */
47
+ export function unresolved(manifest, names) {
48
+ return names.filter((n) => add.lookup(manifest, n).length !== 1);
49
+ }
50
+
40
51
  /** What changed, as two lists of names. Pure, so it can be tested. */
41
52
  export function changes(before, after) {
42
53
  const had = new Set(before);
@@ -47,7 +58,7 @@ export function changes(before, after) {
47
58
  };
48
59
  }
49
60
 
50
- export async function run(opts) {
61
+ export async function run(opts, positionals = []) {
51
62
  const { root, manifest, state } = await requireWorkspace();
52
63
  requireCatalogue(manifest);
53
64
 
@@ -60,6 +71,12 @@ export async function run(opts) {
60
71
  process.exit(1);
61
72
  }
62
73
 
74
+ if (positionals.length) {
75
+ const missing = unresolved(manifest, positionals);
76
+ if (!missing.length) return add.run({ ...opts, removing: false }, positionals);
77
+ warn(`No single repo called ${missing.map((n) => `"${n}"`).join(', ')} — opening the checklist.`);
78
+ }
79
+
63
80
  const before = machineRepos(manifest, state).map((r) => r.name);
64
81
  const { repos } = await chooseRepos({ manifest, root, state, opts: { ...opts, pick: true } });
65
82
  const after = repos.map((r) => r.name);
@@ -6,6 +6,7 @@ export const help = `
6
6
  ${c.bold('talea upgrade')} — update the CLI itself
7
7
 
8
8
  ${c.dim('talea upgrade')} reinstall from npm at the latest version
9
+ ${c.dim('talea update')} the same thing
9
10
  ${c.dim('talea upgrade --check')} only report whether one is available
10
11
  ${c.dim('talea upgrade --on')} turn the daily update notice on
11
12
  ${c.dim('talea upgrade --off')} turn the daily update notice off