@factorialco/fcode-cli 1.2.0 ā 1.4.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 +1 -1
- package/bin/run +10 -1
- package/dist/commands/clone.d.ts +1 -0
- package/dist/commands/clone.js +22 -8
- package/dist/commands/remote/list.js +1 -0
- package/dist/core/types.d.ts +2 -0
- package/dist/services/fcode-graphql-client.js +7 -0
- package/dist/services/resource-checker.js +3 -0
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
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.
|
|
23
|
+
@factorialco/fcode-cli/1.4.0 linux-x64 node-v22.22.3
|
|
24
24
|
$ fcode --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ fcode COMMAND
|
package/bin/run
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const { run, handle, flush } = require('@oclif/core')
|
|
3
|
+
const { run, handle, flush, settings } = require('@oclif/core')
|
|
4
|
+
|
|
5
|
+
// This is the production runner: it always executes the compiled `dist/` output,
|
|
6
|
+
// so oclif must never try to auto-transpile TypeScript sources via ts-node.
|
|
7
|
+
// Otherwise, when the caller's environment has NODE_ENV=development or =test,
|
|
8
|
+
// oclif attempts ts-node and prints "Could not find typescript ... Falling back
|
|
9
|
+
// to compiled source" because typescript is (correctly) not installed in the
|
|
10
|
+
// production dependency tree. Auto-transpile stays enabled for local
|
|
11
|
+
// development through `bin/dev`.
|
|
12
|
+
settings.enableAutoTranspile = false
|
|
4
13
|
|
|
5
14
|
run()
|
|
6
15
|
.catch(async (error) => handle(error))
|
package/dist/commands/clone.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export default class Clone extends Command {
|
|
|
19
19
|
createWorkspaceLocalVariables(slug: string): Promise<void>;
|
|
20
20
|
private skillsInstallHint;
|
|
21
21
|
setupSkills(): Promise<void>;
|
|
22
|
+
private installSkills;
|
|
22
23
|
catch(error: any): Promise<void>;
|
|
23
24
|
init(): Promise<void>;
|
|
24
25
|
mkdirWorkspace(slug: string): Promise<void>;
|
package/dist/commands/clone.js
CHANGED
|
@@ -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
|
-
|
|
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 {
|
|
@@ -75,26 +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 ${
|
|
85
|
+
cli_1.default.log(` npx skills add ${repo} -s '${skills}' -y`);
|
|
81
86
|
}
|
|
82
87
|
async setupSkills() {
|
|
83
88
|
cli_1.default.log('');
|
|
84
|
-
//
|
|
85
|
-
//
|
|
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);
|
|
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'];
|
|
86
100
|
await new Promise((resolve) => {
|
|
87
|
-
const child = (0, node_child_process_1.spawn)('npx',
|
|
101
|
+
const child = (0, node_child_process_1.spawn)('npx', skillsArgs, { stdio: 'inherit' });
|
|
88
102
|
child.on('error', () => {
|
|
89
103
|
// npx not available (or failed to launch) ā don't fail the clone, just tell the user how to do it.
|
|
90
104
|
cli_1.default.log("\nā ļø Couldn't run npx automatically (is Node.js / npx installed?).");
|
|
91
|
-
this.skillsInstallHint();
|
|
105
|
+
this.skillsInstallHint(repo, skills);
|
|
92
106
|
resolve();
|
|
93
107
|
});
|
|
94
108
|
child.on('close', (code) => {
|
|
95
109
|
if (code !== 0) {
|
|
96
110
|
cli_1.default.log("\nā ļø Skill installation didn't complete.");
|
|
97
|
-
this.skillsInstallHint();
|
|
111
|
+
this.skillsInstallHint(repo, skills);
|
|
98
112
|
}
|
|
99
113
|
resolve();
|
|
100
114
|
});
|
|
@@ -6,6 +6,7 @@ const color_1 = require("@oclif/color");
|
|
|
6
6
|
const workspace_1 = require("../../config/workspace");
|
|
7
7
|
class RemoteList extends base_command_1.default {
|
|
8
8
|
async init() {
|
|
9
|
+
await this.parse(RemoteList);
|
|
9
10
|
this.workspaceConfig = new workspace_1.default();
|
|
10
11
|
}
|
|
11
12
|
async run() {
|
package/dist/core/types.d.ts
CHANGED
|
@@ -103,8 +103,10 @@ export interface ProcessWebhook {
|
|
|
103
103
|
username?: string;
|
|
104
104
|
password?: string;
|
|
105
105
|
}
|
|
106
|
+
export type AppRole = 'INSTALL' | 'SETTINGS' | 'USER_FACING_FORM' | 'NONE';
|
|
106
107
|
export interface ProcessForm {
|
|
107
108
|
enabled: boolean;
|
|
109
|
+
appRole?: AppRole;
|
|
108
110
|
}
|
|
109
111
|
export interface ProcessVisibility {
|
|
110
112
|
isPublic: boolean;
|
|
@@ -43,6 +43,7 @@ const PROCESS_FIELDS = `
|
|
|
43
43
|
settings {
|
|
44
44
|
formSettings {
|
|
45
45
|
enabled
|
|
46
|
+
appRole
|
|
46
47
|
}
|
|
47
48
|
publicationConfig {
|
|
48
49
|
isPublic
|
|
@@ -276,6 +277,9 @@ class FcodeGraphQLClient {
|
|
|
276
277
|
};
|
|
277
278
|
if (process.form) {
|
|
278
279
|
settings.formSettings = { enabled: process.form.enabled };
|
|
280
|
+
if (process.form.appRole) {
|
|
281
|
+
settings.formSettings.appRole = process.form.appRole;
|
|
282
|
+
}
|
|
279
283
|
}
|
|
280
284
|
if (process.visibility) {
|
|
281
285
|
settings.publicationConfig = { isPublic: process.visibility.isPublic };
|
|
@@ -569,6 +573,9 @@ class FcodeGraphQLClient {
|
|
|
569
573
|
}
|
|
570
574
|
if (settings?.formSettings) {
|
|
571
575
|
metadata.form = { enabled: Boolean(settings.formSettings.enabled) };
|
|
576
|
+
if (settings.formSettings.appRole && settings.formSettings.appRole !== 'NONE') {
|
|
577
|
+
metadata.form.appRole = settings.formSettings.appRole;
|
|
578
|
+
}
|
|
572
579
|
}
|
|
573
580
|
if (settings?.publicationConfig) {
|
|
574
581
|
metadata.visibility = { isPublic: Boolean(settings.publicationConfig.isPublic) };
|
|
@@ -60,6 +60,9 @@ exports.default = {
|
|
|
60
60
|
case types_1.ResourceStatus.OUT_OF_DATE:
|
|
61
61
|
outOfDateResources.push(remoteResource);
|
|
62
62
|
break;
|
|
63
|
+
case types_1.ResourceStatus.SENSITIVITY_CHANGED:
|
|
64
|
+
outOfDateResources.push(remoteResource);
|
|
65
|
+
break;
|
|
63
66
|
case types_1.ResourceStatus.REMOTE_REMOVED:
|
|
64
67
|
remoteRemovedResources.push(localResource);
|
|
65
68
|
break;
|
package/oclif.manifest.json
CHANGED