uctm 2.0.1 → 2.0.2

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uc-taskmanager",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "agents": [
5
5
  "./agents/orchestrator.md",
6
6
  "./agents/specifier.md",
package/agents/planner.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: planner
3
3
  description: Agent that analyzes projects to create WORK (unit of work) and decompose sub-TASKs. Reads CLAUDE.md, README, and source code to create WORK and derive sub-TASKs.
4
- tools: Read, Glob, Grep, Bash, mcp__serena__*, mcp__sequential-thinking__sequentialthinking
4
+ tools: Read, Write, Edit, Glob, Grep, Bash, mcp__serena__*, mcp__sequential-thinking__sequentialthinking
5
5
  model: opus
6
6
  ---
7
7
 
package/lib/constants.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { readFileSync, existsSync, rmSync } from 'node:fs';
1
+ import { readFileSync, existsSync, rmSync, mkdirSync, copyFileSync, readdirSync, statSync } from 'node:fs';
2
2
  import { join, dirname } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
 
@@ -43,7 +43,7 @@ export function getReferencesSrcDir() {
43
43
  export const OBSOLETE_PATHS = [
44
44
  'agents/scheduler.md', // removed in 2.0.0 — orchestrator took over scheduling
45
45
  'references/callback-protocol.md', // removed in 2.0.0 — external callback integration dropped
46
- 'references/ref-cache-protocol.md',// removed in 2.1.0 — protocol folded into xml-schema.md § 4
46
+ 'references/ref-cache-protocol.md',// removed in 2.0.1 — protocol folded into xml-schema.md § 4
47
47
  'skills/sdd-pipeline/references', // removed in 1.5.0 — references moved to references/
48
48
  ];
49
49
 
@@ -62,6 +62,49 @@ export function pruneObsolete(baseDir) {
62
62
  return removed;
63
63
  }
64
64
 
65
+ /**
66
+ * Recursively copy a directory tree. Shared by init and update.
67
+ * Returns the number of files copied.
68
+ */
69
+ export function copyDirRecursive(src, dest) {
70
+ mkdirSync(dest, { recursive: true });
71
+ let count = 0;
72
+ for (const entry of readdirSync(src)) {
73
+ const srcPath = join(src, entry);
74
+ const destPath = join(dest, entry);
75
+ if (statSync(srcPath).isDirectory()) {
76
+ count += copyDirRecursive(srcPath, destPath);
77
+ } else {
78
+ copyFileSync(srcPath, destPath);
79
+ count++;
80
+ }
81
+ }
82
+ return count;
83
+ }
84
+
85
+ /**
86
+ * Copy plugin resources (.claude-plugin/, skills/) from the package root
87
+ * into the install destination. Shared by init and update.
88
+ */
89
+ export function copyPluginResources(destBaseDir) {
90
+ const pkgRoot = join(__dirname, '..');
91
+ let count = 0;
92
+
93
+ // .claude-plugin/
94
+ const pluginSrc = join(pkgRoot, '.claude-plugin');
95
+ if (existsSync(pluginSrc)) {
96
+ count += copyDirRecursive(pluginSrc, join(destBaseDir, '.claude-plugin'));
97
+ }
98
+
99
+ // skills/
100
+ const skillsSrc = join(pkgRoot, 'skills');
101
+ if (existsSync(skillsSrc)) {
102
+ count += copyDirRecursive(skillsSrc, join(destBaseDir, 'skills'));
103
+ }
104
+
105
+ return count;
106
+ }
107
+
65
108
 
66
109
  /**
67
110
  * Bash permissions required by uc-taskmanager agents.
package/lib/init.mjs CHANGED
@@ -1,10 +1,7 @@
1
- import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync, readdirSync, statSync } from 'node:fs';
1
+ import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import { join, dirname } from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
3
  import { homedir } from 'node:os';
5
- import { AGENT_FILES, REFERENCE_FILES, getAgentsSrcDir, getReferencesSrcDir, REQUIRED_PERMISSIONS, pruneObsolete } from './constants.mjs';
6
-
7
- const __dirname = dirname(fileURLToPath(import.meta.url));
4
+ import { AGENT_FILES, REFERENCE_FILES, getAgentsSrcDir, getReferencesSrcDir, REQUIRED_PERMISSIONS, pruneObsolete, copyPluginResources } from './constants.mjs';
8
5
 
9
6
  import { createInterface } from 'node:readline';
10
7
 
@@ -38,41 +35,6 @@ function copyReferences(destDir) {
38
35
  return count;
39
36
  }
40
37
 
41
- function copyDirRecursive(src, dest) {
42
- mkdirSync(dest, { recursive: true });
43
- let count = 0;
44
- for (const entry of readdirSync(src)) {
45
- const srcPath = join(src, entry);
46
- const destPath = join(dest, entry);
47
- if (statSync(srcPath).isDirectory()) {
48
- count += copyDirRecursive(srcPath, destPath);
49
- } else {
50
- copyFileSync(srcPath, destPath);
51
- count++;
52
- }
53
- }
54
- return count;
55
- }
56
-
57
- function copyPluginResources(destBaseDir) {
58
- const pkgRoot = join(__dirname, '..');
59
- let count = 0;
60
-
61
- // .claude-plugin/
62
- const pluginSrc = join(pkgRoot, '.claude-plugin');
63
- if (existsSync(pluginSrc)) {
64
- count += copyDirRecursive(pluginSrc, join(destBaseDir, '.claude-plugin'));
65
- }
66
-
67
- // skills/
68
- const skillsSrc = join(pkgRoot, 'skills');
69
- if (existsSync(skillsSrc)) {
70
- count += copyDirRecursive(skillsSrc, join(destBaseDir, 'skills'));
71
- }
72
-
73
- return count;
74
- }
75
-
76
38
  function reportPruned(baseDir) {
77
39
  const removed = pruneObsolete(baseDir);
78
40
  if (removed.length === 0) return;
package/lib/update.mjs CHANGED
@@ -2,7 +2,7 @@ import { existsSync, copyFileSync, mkdirSync } from 'node:fs';
2
2
  import { join, dirname } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { homedir } from 'node:os';
5
- import { AGENT_FILES, REFERENCE_FILES, getAgentsSrcDir, getReferencesSrcDir, pruneObsolete } from './constants.mjs';
5
+ import { AGENT_FILES, REFERENCE_FILES, getAgentsSrcDir, getReferencesSrcDir, pruneObsolete, copyPluginResources } from './constants.mjs';
6
6
 
7
7
  const __dirname = dirname(fileURLToPath(import.meta.url));
8
8
 
@@ -40,12 +40,16 @@ export function update(isGlobal) {
40
40
  refCount++;
41
41
  }
42
42
 
43
+ const resCount = copyPluginResources(baseDir);
43
44
  const removed = pruneObsolete(baseDir);
44
45
 
45
46
  const label = isGlobal ? '~/.claude/' : '.claude/';
46
47
  console.log(`\n Updating ${dim(label)} ...`);
47
48
  console.log(` ${green('✓')} ${agentCount} agent files updated`);
48
49
  console.log(` ${green('✓')} ${refCount} reference files updated`);
50
+ if (resCount > 0) {
51
+ console.log(` ${green('✓')} ${resCount} plugin resource files updated`);
52
+ }
49
53
  if (removed.length > 0) {
50
54
  console.log(` ${green('✓')} ${removed.length} obsolete files removed`);
51
55
  for (const relPath of removed) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uctm",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Universal Claude Task Manager — SDD-based task pipeline subagent system for Claude Code CLI",
5
5
  "type": "module",
6
6
  "bin": {