deepline 0.3.63 → 0.3.65
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/dist/bundling-sources/sdk/src/config.ts +153 -13
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +999 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +265 -35
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/test-async-batching.ts +141 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +57 -10
- package/dist/cli/index.js +303 -172
- package/dist/cli/index.mjs +303 -172
- package/dist/index.js +8 -2
- package/dist/index.mjs +8 -2
- package/dist/install-integrity.json +2 -0
- package/package.json +1 -1
|
@@ -47,6 +47,8 @@ import { ConfigError } from './errors.js';
|
|
|
47
47
|
|
|
48
48
|
export const HOST_URL_ENV = 'DEEPLINE_HOST_URL';
|
|
49
49
|
export const API_KEY_ENV = 'DEEPLINE_API_KEY';
|
|
50
|
+
export const ACTIVE_ORG_ID_ENV = 'DEEPLINE_ACTIVE_ORG_ID';
|
|
51
|
+
export const ACTIVE_ORG_NAME_ENV = 'DEEPLINE_ACTIVE_ORG_NAME';
|
|
50
52
|
|
|
51
53
|
/** Production API base URL. */
|
|
52
54
|
const PROD_URL = 'https://code.deepline.com';
|
|
@@ -76,6 +78,21 @@ const COWORK_PROJECT_MARKERS = [
|
|
|
76
78
|
];
|
|
77
79
|
|
|
78
80
|
type EnvValues = Record<string, string>;
|
|
81
|
+
const CLI_ENV_ALLOWED_KEYS = new Set([
|
|
82
|
+
HOST_URL_ENV,
|
|
83
|
+
API_KEY_ENV,
|
|
84
|
+
ACTIVE_ORG_ID_ENV,
|
|
85
|
+
ACTIVE_ORG_NAME_ENV,
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
export type CliCommandContext = {
|
|
89
|
+
active_organization: {
|
|
90
|
+
org_id: string;
|
|
91
|
+
org_name: string | null;
|
|
92
|
+
} | null;
|
|
93
|
+
auth_scope: 'env' | 'folder' | 'global' | null;
|
|
94
|
+
metadata_source: 'process_env' | 'folder_env' | 'host_env' | null;
|
|
95
|
+
};
|
|
79
96
|
type ProjectEnvCandidate = {
|
|
80
97
|
filePath: string;
|
|
81
98
|
env: EnvValues;
|
|
@@ -155,10 +172,16 @@ function parseEnvFile(filePath: string): EnvValues {
|
|
|
155
172
|
if (eqIndex < 0) continue;
|
|
156
173
|
const key = trimmed.slice(0, eqIndex).trim();
|
|
157
174
|
let value = trimmed.slice(eqIndex + 1).trim();
|
|
158
|
-
if (
|
|
175
|
+
if (value.length >= 2 && value.startsWith('"') && value.endsWith('"')) {
|
|
176
|
+
try {
|
|
177
|
+
value = JSON.parse(value) as string;
|
|
178
|
+
} catch {
|
|
179
|
+
value = value.slice(1, -1);
|
|
180
|
+
}
|
|
181
|
+
} else if (
|
|
159
182
|
value.length >= 2 &&
|
|
160
|
-
|
|
161
|
-
|
|
183
|
+
value.startsWith("'") &&
|
|
184
|
+
value.endsWith("'")
|
|
162
185
|
) {
|
|
163
186
|
value = value.slice(1, -1);
|
|
164
187
|
}
|
|
@@ -362,6 +385,35 @@ function firstNonEmpty(...values: Array<string | undefined | null>): string {
|
|
|
362
385
|
return '';
|
|
363
386
|
}
|
|
364
387
|
|
|
388
|
+
function formatEnvFileValue(value: string): string {
|
|
389
|
+
return /^[a-zA-Z0-9_./:@%+=,-]+$/.test(value) ? value : JSON.stringify(value);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function mergePersistedEnvValues(
|
|
393
|
+
existing: EnvValues,
|
|
394
|
+
values: EnvValues,
|
|
395
|
+
): EnvValues {
|
|
396
|
+
const merged = { ...existing, ...values };
|
|
397
|
+
const nextApiKey = values[API_KEY_ENV];
|
|
398
|
+
if (
|
|
399
|
+
nextApiKey !== undefined &&
|
|
400
|
+
nextApiKey !== existing[API_KEY_ENV] &&
|
|
401
|
+
values[ACTIVE_ORG_ID_ENV] === undefined
|
|
402
|
+
) {
|
|
403
|
+
delete merged[ACTIVE_ORG_ID_ENV];
|
|
404
|
+
delete merged[ACTIVE_ORG_NAME_ENV];
|
|
405
|
+
}
|
|
406
|
+
return merged;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function persistedEnvLines(values: EnvValues): string[] {
|
|
410
|
+
return Object.entries(values)
|
|
411
|
+
.filter(
|
|
412
|
+
([key, value]) => CLI_ENV_ALLOWED_KEYS.has(key) && value.trim() !== '',
|
|
413
|
+
)
|
|
414
|
+
.map(([key, value]) => `${key}=${formatEnvFileValue(value)}`);
|
|
415
|
+
}
|
|
416
|
+
|
|
365
417
|
function sdkCliConfigDir(baseUrl: string): string {
|
|
366
418
|
const home = process.env.HOME?.trim() || homedir();
|
|
367
419
|
return join(home, '.local', 'deepline', baseUrlSlug(baseUrl || PROD_URL));
|
|
@@ -404,11 +456,8 @@ export function saveHostEnvValues(baseUrl: string, values: EnvValues): void {
|
|
|
404
456
|
}
|
|
405
457
|
|
|
406
458
|
const existing = parseEnvFile(filePath);
|
|
407
|
-
const merged =
|
|
408
|
-
const
|
|
409
|
-
const lines = Object.entries(merged)
|
|
410
|
-
.filter(([key, value]) => allowedKeys.has(key) && value !== '')
|
|
411
|
-
.map(([key, value]) => `${key}=${value}`);
|
|
459
|
+
const merged = mergePersistedEnvValues(existing, values);
|
|
460
|
+
const lines = persistedEnvLines(merged);
|
|
412
461
|
writeFileSync(filePath, `${lines.join('\n')}\n`, 'utf-8');
|
|
413
462
|
}
|
|
414
463
|
|
|
@@ -520,14 +569,11 @@ export function resolveConfig(options?: DeeplineClientOptions): ResolvedConfig {
|
|
|
520
569
|
|
|
521
570
|
function mergeProjectEnvFile(filePath: string, values: EnvValues): void {
|
|
522
571
|
const existing = parseEnvFile(filePath);
|
|
523
|
-
const merged =
|
|
572
|
+
const merged = mergePersistedEnvValues(existing, values);
|
|
524
573
|
const dir = dirname(filePath);
|
|
525
574
|
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
526
575
|
ensureProjectEnvIsIgnored(dir);
|
|
527
|
-
const
|
|
528
|
-
const lines = Object.entries(merged)
|
|
529
|
-
.filter(([key, value]) => allowedKeys.has(key) && value !== '')
|
|
530
|
-
.map(([key, value]) => `${key}=${value}`);
|
|
576
|
+
const lines = persistedEnvLines(merged);
|
|
531
577
|
writeFileSync(filePath, `${lines.join('\n')}\n`, 'utf-8');
|
|
532
578
|
}
|
|
533
579
|
|
|
@@ -766,6 +812,100 @@ export function resolveCliAuthProvenance(
|
|
|
766
812
|
};
|
|
767
813
|
}
|
|
768
814
|
|
|
815
|
+
function activeOrganizationFromEnv(
|
|
816
|
+
env: EnvValues | NodeJS.ProcessEnv,
|
|
817
|
+
): CliCommandContext['active_organization'] {
|
|
818
|
+
const orgId = env[ACTIVE_ORG_ID_ENV]?.trim();
|
|
819
|
+
if (!orgId) return null;
|
|
820
|
+
const orgName = env[ACTIVE_ORG_NAME_ENV]?.trim() || null;
|
|
821
|
+
return { org_id: orgId, org_name: orgName };
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
/**
|
|
825
|
+
* Resolve display-only organization metadata from the exact credential source
|
|
826
|
+
* selected for this CLI process. The metadata never participates in routing.
|
|
827
|
+
*/
|
|
828
|
+
export function resolveCliCommandContext(
|
|
829
|
+
inputConfig?: Pick<ResolvedConfig, 'baseUrl' | 'apiKey'>,
|
|
830
|
+
requestedScope?: NonNullable<CliCommandContext['auth_scope']>,
|
|
831
|
+
): CliCommandContext {
|
|
832
|
+
let config = inputConfig;
|
|
833
|
+
if (!config) {
|
|
834
|
+
try {
|
|
835
|
+
config = resolveConfig();
|
|
836
|
+
} catch {
|
|
837
|
+
return {
|
|
838
|
+
active_organization: null,
|
|
839
|
+
auth_scope: null,
|
|
840
|
+
metadata_source: null,
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
const contextForScope = (
|
|
846
|
+
scope: NonNullable<CliCommandContext['auth_scope']>,
|
|
847
|
+
): CliCommandContext | null => {
|
|
848
|
+
if (scope === 'env') {
|
|
849
|
+
const processApiKey = process.env[API_KEY_ENV]?.trim();
|
|
850
|
+
return processApiKey && processApiKey === config.apiKey
|
|
851
|
+
? {
|
|
852
|
+
active_organization: activeOrganizationFromEnv(process.env),
|
|
853
|
+
auth_scope: 'env',
|
|
854
|
+
metadata_source: 'process_env',
|
|
855
|
+
}
|
|
856
|
+
: null;
|
|
857
|
+
}
|
|
858
|
+
if (scope === 'folder') {
|
|
859
|
+
const projectAuth = getResolvedProjectAuthSource(
|
|
860
|
+
config.baseUrl,
|
|
861
|
+
config.apiKey,
|
|
862
|
+
);
|
|
863
|
+
return projectAuth
|
|
864
|
+
? {
|
|
865
|
+
active_organization: activeOrganizationFromEnv(projectAuth.env),
|
|
866
|
+
auth_scope: 'folder',
|
|
867
|
+
metadata_source: 'folder_env',
|
|
868
|
+
}
|
|
869
|
+
: null;
|
|
870
|
+
}
|
|
871
|
+
const hostEnv = loadCliEnv(config.baseUrl);
|
|
872
|
+
return (hostEnv[API_KEY_ENV] ?? '').trim() === config.apiKey
|
|
873
|
+
? {
|
|
874
|
+
active_organization: activeOrganizationFromEnv(hostEnv),
|
|
875
|
+
auth_scope: 'global',
|
|
876
|
+
metadata_source: 'host_env',
|
|
877
|
+
}
|
|
878
|
+
: null;
|
|
879
|
+
};
|
|
880
|
+
|
|
881
|
+
// An explicit process key always wins credential resolution, even when a
|
|
882
|
+
// command accepts --auth-scope to select a saved fallback. Report the
|
|
883
|
+
// provenance of the key the command actually used.
|
|
884
|
+
const processContext = contextForScope('env');
|
|
885
|
+
if (processContext) return processContext;
|
|
886
|
+
|
|
887
|
+
if (requestedScope) {
|
|
888
|
+
return (
|
|
889
|
+
contextForScope(requestedScope) ?? {
|
|
890
|
+
active_organization: null,
|
|
891
|
+
auth_scope: requestedScope,
|
|
892
|
+
metadata_source: null,
|
|
893
|
+
}
|
|
894
|
+
);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
for (const scope of ['folder', 'global'] as const) {
|
|
898
|
+
const context = contextForScope(scope);
|
|
899
|
+
if (context) return context;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
return {
|
|
903
|
+
active_organization: null,
|
|
904
|
+
auth_scope: null,
|
|
905
|
+
metadata_source: null,
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
|
|
769
909
|
export {
|
|
770
910
|
baseUrlSlug,
|
|
771
911
|
loadCliEnv,
|
|
@@ -199,7 +199,7 @@ export const SDK_RELEASE = {
|
|
|
199
199
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
200
200
|
// getters keep their established compatibility behavior.
|
|
201
201
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
202
|
-
version: '0.3.
|
|
202
|
+
version: '0.3.65',
|
|
203
203
|
updateSummary:
|
|
204
204
|
'Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.',
|
|
205
205
|
packageCapabilities: {
|