@factorialco/fcode-cli 1.3.0 → 1.5.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/README.md CHANGED
@@ -20,7 +20,7 @@ $ npm install -g @factorialco/fcode-cli
20
20
  $ fcode COMMAND
21
21
  running command...
22
22
  $ fcode (--version)
23
- @factorialco/fcode-cli/1.3.0 linux-x64 node-v22.22.3
23
+ @factorialco/fcode-cli/1.5.0 linux-x64 node-v22.22.3
24
24
  $ fcode --help [COMMAND]
25
25
  USAGE
26
26
  $ fcode COMMAND
@@ -100,14 +100,12 @@ Clone team workspace from cloud
100
100
 
101
101
  ```
102
102
  USAGE
103
- $ fcode clone [TEAM] [--skipSkillsSetup] [--autoSkillsSetup]
103
+ $ fcode clone [TEAM] [--skipSkillsSetup]
104
104
 
105
105
  ARGUMENTS
106
106
  [TEAM] Team name
107
107
 
108
108
  FLAGS
109
- --autoSkillsSetup Install the Factorial Code agent skills non-interactively (defaults, project scope) instead of
110
- prompting
111
109
  --skipSkillsSetup Skip installation of the Factorial Code agent skills
112
110
 
113
111
  DESCRIPTION
@@ -8,18 +8,18 @@ export default class Clone extends Command {
8
8
  static examples: string[];
9
9
  static flags: {
10
10
  skipSkillsSetup: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
- autoSkillsSetup: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
11
  };
13
12
  checkWorkspaceAlreadyCloned(slug: string): Promise<void>;
14
13
  checkWorkspaceIsEmpty(slug: string): Promise<void>;
15
- cloneTeam(origin: TeamOrigin, skipSkillsSetup?: boolean, autoSkillsSetup?: boolean): Promise<void>;
14
+ cloneTeam(origin: TeamOrigin, skipSkillsSetup?: boolean): Promise<void>;
16
15
  createWorkspaceConfig(origin: TeamOrigin): Promise<void>;
17
16
  createWorkspaceDatastore(slug: string): void;
18
17
  createWorkspaceStorage(slug: string): void;
19
18
  createWorkspaceGitIgnore(slug: string): Promise<void>;
20
19
  createWorkspaceLocalVariables(slug: string): Promise<void>;
21
20
  private skillsInstallHint;
22
- setupSkills(autoSkillsSetup?: boolean): Promise<void>;
21
+ setupSkills(): Promise<void>;
22
+ private installSkills;
23
23
  catch(error: any): Promise<void>;
24
24
  init(): Promise<void>;
25
25
  mkdirWorkspace(slug: string): Promise<void>;
@@ -10,7 +10,12 @@ const pull_1 = require("./pull");
10
10
  const types_1 = require("../core/types");
11
11
  const cli_1 = require("../utils/cli");
12
12
  const settings_1 = require("../config/settings");
13
- const SKILLS_REPO = 'factorialco/factorial-code-skills';
13
+ // Skill sources installed on clone. `release-sdk` in factorial-api-sdks is a
14
+ // maintainer-only skill, so we pick `factorial-api-sdks` explicitly there.
15
+ const SKILLS_SOURCES = [
16
+ { repo: 'factorialco/factorial-code-skills', skills: '*' },
17
+ { repo: 'factorialco/factorial-api-sdks', skills: 'factorial-api-sdks' },
18
+ ];
14
19
  class Clone extends core_1.Command {
15
20
  async checkWorkspaceAlreadyCloned(slug) {
16
21
  try {
@@ -41,7 +46,7 @@ class Clone extends core_1.Command {
41
46
  });
42
47
  }
43
48
  }
44
- async cloneTeam(origin, skipSkillsSetup = false, autoSkillsSetup = false) {
49
+ async cloneTeam(origin, skipSkillsSetup = false) {
45
50
  await this.mkdirWorkspace(origin.slug);
46
51
  await this.createWorkspaceConfig(origin);
47
52
  await this.createWorkspaceGitIgnore(origin.slug);
@@ -51,7 +56,7 @@ class Clone extends core_1.Command {
51
56
  process.chdir(origin.slug);
52
57
  await pull_1.default.run([]);
53
58
  if (!skipSkillsSetup) {
54
- await this.setupSkills(autoSkillsSetup);
59
+ await this.setupSkills();
55
60
  }
56
61
  }
57
62
  async createWorkspaceConfig(origin) {
@@ -75,32 +80,35 @@ class Clone extends core_1.Command {
75
80
  const localVariablesFileName = await globalConfig.getSetting(settings_1.SettingKeys.LOCAL_VARIABLES_FILE_NAME);
76
81
  fs.outputFileSync(path.join(slug, localVariablesFileName), '');
77
82
  }
78
- skillsInstallHint() {
83
+ skillsInstallHint(repo, skills) {
79
84
  cli_1.default.log('šŸ’” Install the Factorial Code agent skills later with:');
80
- cli_1.default.log(` npx skills add ${SKILLS_REPO} -s '*'`);
85
+ cli_1.default.log(` npx skills add ${repo} -s '${skills}' -y`);
81
86
  }
82
- async setupSkills(autoSkillsSetup = false) {
87
+ async setupSkills() {
83
88
  cli_1.default.log('');
84
- // `npx --yes skills add <repo> -s '*'` — preselect all skills; the skills CLI
85
- // then handles scope (project/global) and assistant selection interactively.
86
- // With autoSkillsSetup, add the skills CLI's `-y` flag so it installs
87
- // non-interactively using its defaults, project-scoped (no `-g`), without prompting.
88
- const skillsArgs = ['--yes', 'skills', 'add', SKILLS_REPO, '-s', '*'];
89
- if (autoSkillsSetup) {
90
- skillsArgs.push('-y');
89
+ // The skills CLI only installs to agents it detects; a fresh workspace has no
90
+ // agent directories, so create .claude/ first so Claude Code is always targeted.
91
+ fs.ensureDirSync('.claude');
92
+ for (const source of SKILLS_SOURCES) {
93
+ await this.installSkills(source.repo, source.skills);
91
94
  }
95
+ }
96
+ async installSkills(repo, skills) {
97
+ // `npx --yes skills add <repo> -s <skills> -y` — non-interactive install with
98
+ // the skills CLI defaults: project scope (no -g), symlinked (no --copy).
99
+ const skillsArgs = ['--yes', 'skills', 'add', repo, '-s', skills, '-y'];
92
100
  await new Promise((resolve) => {
93
101
  const child = (0, node_child_process_1.spawn)('npx', skillsArgs, { stdio: 'inherit' });
94
102
  child.on('error', () => {
95
103
  // npx not available (or failed to launch) — don't fail the clone, just tell the user how to do it.
96
104
  cli_1.default.log("\nāš ļø Couldn't run npx automatically (is Node.js / npx installed?).");
97
- this.skillsInstallHint();
105
+ this.skillsInstallHint(repo, skills);
98
106
  resolve();
99
107
  });
100
108
  child.on('close', (code) => {
101
109
  if (code !== 0) {
102
110
  cli_1.default.log("\nāš ļø Skill installation didn't complete.");
103
- this.skillsInstallHint();
111
+ this.skillsInstallHint(repo, skills);
104
112
  }
105
113
  resolve();
106
114
  });
@@ -167,11 +175,7 @@ class Clone extends core_1.Command {
167
175
  if (skipSkillsSetup === undefined) {
168
176
  skipSkillsSetup = (await new global_1.default().getSetting(settings_1.SettingKeys.SKIP_SKILLS_SETUP)) === 'true';
169
177
  }
170
- let autoSkillsSetup = flags.autoSkillsSetup;
171
- if (autoSkillsSetup === undefined) {
172
- autoSkillsSetup = (await new global_1.default().getSetting(settings_1.SettingKeys.AUTO_SKILLS_SETUP)) === 'true';
173
- }
174
- await this.cloneTeam({ url, slug }, skipSkillsSetup, autoSkillsSetup);
178
+ await this.cloneTeam({ url, slug }, skipSkillsSetup);
175
179
  cli_1.default.log(`\nšŸŽ‰ ${args.team} team workspace cloned successfully!\n`);
176
180
  cli_1.default.log(`$ cd ${slug}\n`);
177
181
  }
@@ -183,8 +187,5 @@ Clone.flags = {
183
187
  skipSkillsSetup: core_1.Flags.boolean({
184
188
  description: 'Skip installation of the Factorial Code agent skills',
185
189
  }),
186
- autoSkillsSetup: core_1.Flags.boolean({
187
- description: 'Install the Factorial Code agent skills non-interactively (defaults, project scope) instead of prompting',
188
- }),
189
190
  };
190
191
  exports.default = Clone;
@@ -4,7 +4,6 @@ export interface SettingDefinition {
4
4
  description?: string;
5
5
  }
6
6
  export declare enum SettingKeys {
7
- AUTO_SKILLS_SETUP = "autoSkillsSetup",
8
7
  DISABLE_UPDATE_NOTIFIER = "disableUpdateNotifier",
9
8
  IGNORE_PROCESS_VERSIONS = "ignoreProcessVersions",
10
9
  IGNORE_WORKSPACE_NOT_EMPTY = "ignoreWorkspaceNotEmpty",
@@ -4,7 +4,6 @@ exports.SETTINGS_DEFINITIONS = exports.SettingKeys = void 0;
4
4
  exports.getSettingDefault = getSettingDefault;
5
5
  var SettingKeys;
6
6
  (function (SettingKeys) {
7
- SettingKeys["AUTO_SKILLS_SETUP"] = "autoSkillsSetup";
8
7
  SettingKeys["DISABLE_UPDATE_NOTIFIER"] = "disableUpdateNotifier";
9
8
  SettingKeys["IGNORE_PROCESS_VERSIONS"] = "ignoreProcessVersions";
10
9
  SettingKeys["IGNORE_WORKSPACE_NOT_EMPTY"] = "ignoreWorkspaceNotEmpty";
@@ -29,11 +28,6 @@ exports.SETTINGS_DEFINITIONS = [
29
28
  default: 'false',
30
29
  description: 'Skip Factorial Code agent skills install on clone',
31
30
  },
32
- {
33
- key: SettingKeys.AUTO_SKILLS_SETUP,
34
- default: 'false',
35
- description: 'Install Factorial Code agent skills non-interactively (defaults, project scope) on clone',
36
- },
37
31
  {
38
32
  key: SettingKeys.IGNORE_FCODE_RUN_PROCESSES,
39
33
  default: 'false',
@@ -103,11 +103,10 @@ export interface ProcessWebhook {
103
103
  username?: string;
104
104
  password?: string;
105
105
  }
106
+ export type AppRole = 'INSTALL' | 'SETTINGS' | 'USER_FACING_FORM' | 'UNINSTALL' | 'NONE';
106
107
  export interface ProcessForm {
107
108
  enabled: boolean;
108
- }
109
- export interface ProcessVisibility {
110
- isPublic: boolean;
109
+ appRole?: AppRole;
111
110
  }
112
111
  export interface ProcessMetadataFields {
113
112
  name: string;
@@ -115,7 +114,6 @@ export interface ProcessMetadataFields {
115
114
  tags: string[];
116
115
  webhook?: ProcessWebhook;
117
116
  form?: ProcessForm;
118
- visibility?: ProcessVisibility;
119
117
  }
120
118
  export declare class Process extends Resource {
121
119
  id: string;
@@ -126,7 +124,6 @@ export declare class Process extends Resource {
126
124
  tags: string[];
127
125
  webhook?: ProcessWebhook;
128
126
  form?: ProcessForm;
129
- visibility?: ProcessVisibility;
130
127
  script: {
131
128
  parametersSchema: any;
132
129
  programmingLanguage: ProgrammingLanguage;
@@ -47,7 +47,6 @@ class Process extends Resource {
47
47
  this.tags = metadata.tags;
48
48
  this.webhook = metadata.webhook;
49
49
  this.form = metadata.form;
50
- this.visibility = metadata.visibility;
51
50
  this.script = script;
52
51
  this.readme = readme;
53
52
  this.manifest = settings.dependencies.scopedToProcess && manifest !== null ? manifest : { dependencies: [] };
@@ -64,7 +63,6 @@ class Process extends Resource {
64
63
  tags: this.tags || [],
65
64
  webhook: this.webhook || null,
66
65
  form: this.form || null,
67
- visibility: this.visibility || null,
68
66
  manifestDependencies: this.manifest.dependencies,
69
67
  dependenciesScopedToProcess: this.settings.dependencies.scopedToProcess,
70
68
  });
@@ -136,7 +136,6 @@ class ProcessRepository extends resource_1.default {
136
136
  tags: Array.isArray(raw.tags) ? raw.tags : [],
137
137
  webhook: raw.webhook,
138
138
  form: raw.form,
139
- visibility: raw.visibility,
140
139
  };
141
140
  }
142
141
  catch (error) {
@@ -157,9 +156,6 @@ class ProcessRepository extends resource_1.default {
157
156
  if (process.form !== undefined) {
158
157
  metadata.form = process.form;
159
158
  }
160
- if (process.visibility !== undefined) {
161
- metadata.visibility = process.visibility;
162
- }
163
159
  return metadata;
164
160
  }
165
161
  async findParameters(processSlug) {
@@ -43,9 +43,7 @@ const PROCESS_FIELDS = `
43
43
  settings {
44
44
  formSettings {
45
45
  enabled
46
- }
47
- publicationConfig {
48
- isPublic
46
+ appRole
49
47
  }
50
48
  dependencies {
51
49
  scopedToProcess
@@ -276,9 +274,9 @@ class FcodeGraphQLClient {
276
274
  };
277
275
  if (process.form) {
278
276
  settings.formSettings = { enabled: process.form.enabled };
279
- }
280
- if (process.visibility) {
281
- settings.publicationConfig = { isPublic: process.visibility.isPublic };
277
+ if (process.form.appRole) {
278
+ settings.formSettings.appRole = process.form.appRole;
279
+ }
282
280
  }
283
281
  const input = {
284
282
  name: process.name,
@@ -569,9 +567,9 @@ class FcodeGraphQLClient {
569
567
  }
570
568
  if (settings?.formSettings) {
571
569
  metadata.form = { enabled: Boolean(settings.formSettings.enabled) };
572
- }
573
- if (settings?.publicationConfig) {
574
- metadata.visibility = { isPublic: Boolean(settings.publicationConfig.isPublic) };
570
+ if (settings.formSettings.appRole && settings.formSettings.appRole !== 'NONE') {
571
+ metadata.form.appRole = settings.formSettings.appRole;
572
+ }
575
573
  }
576
574
  return new types_1.Process(id, slug, script, readme, { dependencies }, settings, metadata, this.inheritedTeam(resolvingTeamSlug));
577
575
  }
@@ -41,12 +41,6 @@
41
41
  "name": "skipSkillsSetup",
42
42
  "allowNo": false,
43
43
  "type": "boolean"
44
- },
45
- "autoSkillsSetup": {
46
- "description": "Install the Factorial Code agent skills non-interactively (defaults, project scope) instead of prompting",
47
- "name": "autoSkillsSetup",
48
- "allowNo": false,
49
- "type": "boolean"
50
44
  }
51
45
  },
52
46
  "hasDynamicHelp": false,
@@ -1485,83 +1479,6 @@
1485
1479
  "set.js"
1486
1480
  ]
1487
1481
  },
1488
- "team:pull": {
1489
- "aliases": [],
1490
- "args": {},
1491
- "description": "Fetch team settings (timezone, error handler, inheritance) from cloud into team.json",
1492
- "examples": [
1493
- "$ fcode team:pull"
1494
- ],
1495
- "flags": {},
1496
- "hasDynamicHelp": false,
1497
- "hiddenAliases": [],
1498
- "id": "team:pull",
1499
- "pluginAlias": "@factorialco/fcode-cli",
1500
- "pluginName": "@factorialco/fcode-cli",
1501
- "pluginType": "core",
1502
- "strict": true,
1503
- "isESM": false,
1504
- "relativePath": [
1505
- "dist",
1506
- "commands",
1507
- "team",
1508
- "pull.js"
1509
- ]
1510
- },
1511
- "team:push": {
1512
- "aliases": [],
1513
- "args": {},
1514
- "description": "Update cloud team settings (timezone, error handler, inheritance) from team.json",
1515
- "examples": [
1516
- "$ fcode team:push"
1517
- ],
1518
- "flags": {
1519
- "force": {
1520
- "char": "f",
1521
- "description": "Force command",
1522
- "name": "force",
1523
- "allowNo": false,
1524
- "type": "boolean"
1525
- }
1526
- },
1527
- "hasDynamicHelp": false,
1528
- "hiddenAliases": [],
1529
- "id": "team:push",
1530
- "pluginAlias": "@factorialco/fcode-cli",
1531
- "pluginName": "@factorialco/fcode-cli",
1532
- "pluginType": "core",
1533
- "strict": true,
1534
- "isESM": false,
1535
- "relativePath": [
1536
- "dist",
1537
- "commands",
1538
- "team",
1539
- "push.js"
1540
- ]
1541
- },
1542
- "team:status": {
1543
- "aliases": [],
1544
- "args": {},
1545
- "description": "Show whether team settings (timezone, error handler, inheritance) differ from the cloud",
1546
- "examples": [
1547
- "$ fcode team:status"
1548
- ],
1549
- "flags": {},
1550
- "hasDynamicHelp": false,
1551
- "hiddenAliases": [],
1552
- "id": "team:status",
1553
- "pluginAlias": "@factorialco/fcode-cli",
1554
- "pluginName": "@factorialco/fcode-cli",
1555
- "pluginType": "core",
1556
- "strict": true,
1557
- "isESM": false,
1558
- "relativePath": [
1559
- "dist",
1560
- "commands",
1561
- "team",
1562
- "status.js"
1563
- ]
1564
- },
1565
1482
  "test:scaffold": {
1566
1483
  "aliases": [],
1567
1484
  "args": {
@@ -1783,7 +1700,84 @@
1783
1700
  "variables",
1784
1701
  "status.js"
1785
1702
  ]
1703
+ },
1704
+ "team:pull": {
1705
+ "aliases": [],
1706
+ "args": {},
1707
+ "description": "Fetch team settings (timezone, error handler, inheritance) from cloud into team.json",
1708
+ "examples": [
1709
+ "$ fcode team:pull"
1710
+ ],
1711
+ "flags": {},
1712
+ "hasDynamicHelp": false,
1713
+ "hiddenAliases": [],
1714
+ "id": "team:pull",
1715
+ "pluginAlias": "@factorialco/fcode-cli",
1716
+ "pluginName": "@factorialco/fcode-cli",
1717
+ "pluginType": "core",
1718
+ "strict": true,
1719
+ "isESM": false,
1720
+ "relativePath": [
1721
+ "dist",
1722
+ "commands",
1723
+ "team",
1724
+ "pull.js"
1725
+ ]
1726
+ },
1727
+ "team:push": {
1728
+ "aliases": [],
1729
+ "args": {},
1730
+ "description": "Update cloud team settings (timezone, error handler, inheritance) from team.json",
1731
+ "examples": [
1732
+ "$ fcode team:push"
1733
+ ],
1734
+ "flags": {
1735
+ "force": {
1736
+ "char": "f",
1737
+ "description": "Force command",
1738
+ "name": "force",
1739
+ "allowNo": false,
1740
+ "type": "boolean"
1741
+ }
1742
+ },
1743
+ "hasDynamicHelp": false,
1744
+ "hiddenAliases": [],
1745
+ "id": "team:push",
1746
+ "pluginAlias": "@factorialco/fcode-cli",
1747
+ "pluginName": "@factorialco/fcode-cli",
1748
+ "pluginType": "core",
1749
+ "strict": true,
1750
+ "isESM": false,
1751
+ "relativePath": [
1752
+ "dist",
1753
+ "commands",
1754
+ "team",
1755
+ "push.js"
1756
+ ]
1757
+ },
1758
+ "team:status": {
1759
+ "aliases": [],
1760
+ "args": {},
1761
+ "description": "Show whether team settings (timezone, error handler, inheritance) differ from the cloud",
1762
+ "examples": [
1763
+ "$ fcode team:status"
1764
+ ],
1765
+ "flags": {},
1766
+ "hasDynamicHelp": false,
1767
+ "hiddenAliases": [],
1768
+ "id": "team:status",
1769
+ "pluginAlias": "@factorialco/fcode-cli",
1770
+ "pluginName": "@factorialco/fcode-cli",
1771
+ "pluginType": "core",
1772
+ "strict": true,
1773
+ "isESM": false,
1774
+ "relativePath": [
1775
+ "dist",
1776
+ "commands",
1777
+ "team",
1778
+ "status.js"
1779
+ ]
1786
1780
  }
1787
1781
  },
1788
- "version": "1.3.0"
1782
+ "version": "1.5.0"
1789
1783
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@factorialco/fcode-cli",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "packageManager": "pnpm@11.7.0",
5
5
  "description": "Factorial Code Command Line Interface",
6
6
  "homepage": "https://code.factorialhr.com/docs/cli/",