@pikku/core 0.12.24 → 0.12.25

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/data-classification.d.ts +16 -0
  3. package/dist/data-classification.js +1 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/services/gopass-secrets.d.ts +2 -35
  6. package/dist/services/gopass-secrets.js +10 -40
  7. package/dist/services/local-secrets.d.ts +2 -36
  8. package/dist/services/local-secrets.js +3 -52
  9. package/dist/services/local-variables.d.ts +3 -5
  10. package/dist/services/local-variables.js +10 -10
  11. package/dist/services/scoped-secret-service.d.ts +2 -3
  12. package/dist/services/scoped-secret-service.js +2 -6
  13. package/dist/services/secret-service.d.ts +5 -12
  14. package/dist/services/typed-secret-service.d.ts +3 -4
  15. package/dist/services/typed-secret-service.js +2 -5
  16. package/dist/services/typed-variables-service.d.ts +3 -6
  17. package/dist/services/typed-variables-service.js +0 -6
  18. package/dist/services/variables-service.d.ts +2 -4
  19. package/dist/testing/service-tests.js +13 -13
  20. package/dist/wirings/ai-agent/ai-agent-prepare.js +4 -1
  21. package/dist/wirings/ai-agent/ai-agent.types.d.ts +4 -0
  22. package/dist/wirings/oauth2/oauth2-client.js +3 -3
  23. package/package.json +1 -1
  24. package/src/data-classification.ts +15 -0
  25. package/src/index.ts +9 -0
  26. package/src/services/gopass-secrets.ts +10 -42
  27. package/src/services/local-secrets.test.ts +10 -10
  28. package/src/services/local-secrets.ts +11 -59
  29. package/src/services/local-variables.test.ts +4 -4
  30. package/src/services/local-variables.ts +12 -17
  31. package/src/services/scoped-secret-service.test.ts +10 -11
  32. package/src/services/scoped-secret-service.ts +4 -9
  33. package/src/services/secret-service.ts +5 -12
  34. package/src/services/typed-secret-service.test.ts +16 -17
  35. package/src/services/typed-secret-service.ts +5 -9
  36. package/src/services/typed-variables-service.test.ts +5 -5
  37. package/src/services/typed-variables-service.ts +5 -17
  38. package/src/services/variables-service.ts +2 -4
  39. package/src/testing/service-tests.ts +13 -13
  40. package/src/wirings/ai-agent/ai-agent-prepare.ts +7 -2
  41. package/src/wirings/ai-agent/ai-agent.types.ts +4 -0
  42. package/src/wirings/oauth2/oauth2-client.test.ts +2 -3
  43. package/src/wirings/oauth2/oauth2-client.ts +3 -3
  44. package/tsconfig.tsbuildinfo +1 -1
@@ -20,20 +20,12 @@ export class TypedVariablesService<
20
20
  private variablesMeta: Record<string, VariableMeta>
21
21
  ) {}
22
22
 
23
- get(
24
- name: keyof TMap & string
25
- ): Promise<string | undefined> | string | undefined
26
- get(name: string): Promise<string | undefined> | string | undefined
27
- get(name: string): Promise<string | undefined> | string | undefined {
28
- return this.variables.get(name)
29
- }
30
-
31
- getJSON<K extends keyof TMap & string>(
23
+ get<K extends keyof TMap & string>(
32
24
  name: K
33
25
  ): Promise<TMap[K] | undefined> | TMap[K] | undefined
34
- getJSON<T = unknown>(name: string): Promise<T | undefined> | T | undefined
35
- getJSON(name: string): Promise<unknown> | unknown {
36
- return this.variables.getJSON(name)
26
+ get<T = string>(name: string): Promise<T | undefined> | T | undefined
27
+ get(name: string): Promise<unknown> | unknown {
28
+ return this.variables.get(name)
37
29
  }
38
30
 
39
31
  getAll():
@@ -42,14 +34,10 @@ export class TypedVariablesService<
42
34
  return this.variables.getAll()
43
35
  }
44
36
 
45
- set(name: string, value: string): Promise<void> | void {
37
+ set(name: string, value: unknown): Promise<void> | void {
46
38
  return this.variables.set(name, value)
47
39
  }
48
40
 
49
- setJSON(name: string, value: unknown): Promise<void> | void {
50
- return this.variables.setJSON(name, value)
51
- }
52
-
53
41
  has(name: string): Promise<boolean> | boolean {
54
42
  return this.variables.has(name)
55
43
  }
@@ -1,11 +1,9 @@
1
1
  export interface VariablesService {
2
- get: (name: string) => Promise<string | undefined> | string | undefined
3
- getJSON: <T = unknown>(name: string) => Promise<T | undefined> | T | undefined
2
+ get<T = string>(name: string): Promise<T | undefined> | T | undefined
4
3
  getAll: () =>
5
4
  | Promise<Record<string, string | undefined>>
6
5
  | Record<string, string | undefined>
7
- set: (name: string, value: string) => Promise<void> | void
8
- setJSON: (name: string, value: unknown) => Promise<void> | void
6
+ set: (name: string, value: unknown) => Promise<void> | void
9
7
  has: (name: string) => Promise<boolean> | boolean
10
8
  delete: (name: string) => Promise<void> | void
11
9
  }
@@ -782,13 +782,13 @@ export function defineServiceTests(config: ServiceTestConfig): void {
782
782
  const kek = 'test-key-encryption-key-32chars!'
783
783
 
784
784
  describe(`SecretService [${name}]`, () => {
785
- test('setSecretJSON and getSecretJSON', async () => {
785
+ test('setSecret and getSecret', async () => {
786
786
  const service = await factory({ key: kek })
787
- await service.setSecretJSON('api-key', {
787
+ await service.setSecret('api-key', {
788
788
  token: 'sk-123',
789
789
  endpoint: 'https://api.example.com',
790
790
  })
791
- const result = await service.getSecretJSON<{
791
+ const result = await service.getSecret<{
792
792
  token: string
793
793
  endpoint: string
794
794
  }>('api-key')
@@ -800,9 +800,9 @@ export function defineServiceTests(config: ServiceTestConfig): void {
800
800
 
801
801
  test('getSecret returns raw string', async () => {
802
802
  const service = await factory({ key: kek })
803
- await service.setSecretJSON('string-secret', 'plain-value')
803
+ await service.setSecret('string-secret', 'plain-value')
804
804
  const result = await service.getSecret('string-secret')
805
- assert.strictEqual(result, '"plain-value"')
805
+ assert.strictEqual(result, 'plain-value')
806
806
  })
807
807
 
808
808
  test('hasSecret returns true/false', async () => {
@@ -818,17 +818,17 @@ export function defineServiceTests(config: ServiceTestConfig): void {
818
818
  })
819
819
  })
820
820
 
821
- test('setSecretJSON upserts existing key', async () => {
821
+ test('setSecret upserts existing key', async () => {
822
822
  const service = await factory({ key: kek })
823
- await service.setSecretJSON('upsert-key', { v: 1 })
824
- await service.setSecretJSON('upsert-key', { v: 2 })
825
- const result = await service.getSecretJSON<{ v: number }>('upsert-key')
823
+ await service.setSecret('upsert-key', { v: 1 })
824
+ await service.setSecret('upsert-key', { v: 2 })
825
+ const result = await service.getSecret<{ v: number }>('upsert-key')
826
826
  assert.deepEqual(result, { v: 2 })
827
827
  })
828
828
 
829
829
  test('deleteSecret removes the key', async () => {
830
830
  const service = await factory({ key: kek })
831
- await service.setSecretJSON('to-delete', 'bye')
831
+ await service.setSecret('to-delete', 'bye')
832
832
  assert.strictEqual(await service.hasSecret('to-delete'), true)
833
833
  await service.deleteSecret('to-delete')
834
834
  assert.strictEqual(await service.hasSecret('to-delete'), false)
@@ -837,7 +837,7 @@ export function defineServiceTests(config: ServiceTestConfig): void {
837
837
  test('rotateKEK re-wraps all secrets', async () => {
838
838
  const newKEK = 'new-key-encryption-key-rotated!'
839
839
  const oldService = await factory({ key: kek })
840
- await oldService.setSecretJSON('rotate-test', { important: 'data' })
840
+ await oldService.setSecret('rotate-test', { important: 'data' })
841
841
 
842
842
  const rotatedService = await factory({
843
843
  key: newKEK,
@@ -845,7 +845,7 @@ export function defineServiceTests(config: ServiceTestConfig): void {
845
845
  previousKey: kek,
846
846
  })
847
847
 
848
- const before = await rotatedService.getSecretJSON<{
848
+ const before = await rotatedService.getSecret<{
849
849
  important: string
850
850
  }>('rotate-test')
851
851
  assert.deepEqual(before, { important: 'data' })
@@ -858,7 +858,7 @@ export function defineServiceTests(config: ServiceTestConfig): void {
858
858
  key: newKEK,
859
859
  keyVersion: 2,
860
860
  })
861
- const after = await newOnlyService.getSecretJSON<{
861
+ const after = await newOnlyService.getSecret<{
862
862
  important: string
863
863
  }>('rotate-test')
864
864
  assert.deepEqual(after, { important: 'data' })
@@ -624,7 +624,9 @@ export async function prepareAgentRun(
624
624
  }
625
625
 
626
626
  if (params.getCredential && agentRunner.withApiKey) {
627
- const aiCredential = await params.getCredential<{ apiKey: string }>('AI_API_KEY')
627
+ const aiCredential = await params.getCredential<{ apiKey: string }>(
628
+ 'AI_API_KEY'
629
+ )
628
630
  if (aiCredential?.apiKey?.trim()) {
629
631
  agentRunner = agentRunner.withApiKey(aiCredential.apiKey)
630
632
  }
@@ -707,7 +709,10 @@ export async function prepareAgentRun(
707
709
  agent.agentMode
708
710
  )
709
711
 
710
- const instructions = await buildInstructions(resolvedName, packageName)
712
+ let instructions = await buildInstructions(resolvedName, packageName)
713
+ if (input.context) {
714
+ instructions = `${instructions}\n\nCurrent context (use these identifiers directly in tool calls — do not ask the user for them):\n${input.context}`
715
+ }
711
716
 
712
717
  const resolved = resolveModelConfig(resolvedName, agent)
713
718
 
@@ -81,6 +81,10 @@ export interface AIAgentInput {
81
81
  attachments?: AIAgentInputAttachment[]
82
82
  model?: string
83
83
  temperature?: number
84
+ /** Structured context injected into the system instructions for this request.
85
+ * Use to provide upfront state (e.g. current org/project/branch/deployment)
86
+ * so the agent can call tools without asking the user for identifiers. */
87
+ context?: string
84
88
  }
85
89
 
86
90
  export interface AIAgentOutput {
@@ -14,9 +14,8 @@ function createMockSecretService(
14
14
  ): SecretService & { getStoredSecrets: () => Map<string, unknown> } {
15
15
  const secrets = new Map<string, unknown>(Object.entries(initialSecrets))
16
16
  return {
17
- getSecret: async (key: string) => secrets.get(key) as string,
18
- getSecretJSON: async <T>(key: string) => secrets.get(key) as T,
19
- setSecretJSON: async (key: string, value: unknown) => {
17
+ getSecret: async <T = string>(key: string) => secrets.get(key) as T,
18
+ setSecret: async (key: string, value: unknown) => {
20
19
  secrets.set(key, value)
21
20
  },
22
21
  deleteSecret: async (_key: string) => {
@@ -124,7 +124,7 @@ export class OAuth2Client {
124
124
  }
125
125
 
126
126
  // Load from secrets
127
- const token = await this.secrets.getSecretJSON<OAuth2Token>(
127
+ const token = await this.secrets.getSecret<OAuth2Token>(
128
128
  this.oauth2Config.tokenSecretId
129
129
  )
130
130
  this.cachedToken = token
@@ -209,7 +209,7 @@ export class OAuth2Client {
209
209
  scope: data.scope,
210
210
  }
211
211
 
212
- await this.secrets.setSecretJSON(this.oauth2Config.tokenSecretId, token)
212
+ await this.secrets.setSecret(this.oauth2Config.tokenSecretId, token)
213
213
  this.cachedToken = token
214
214
 
215
215
  return token
@@ -233,7 +233,7 @@ export class OAuth2Client {
233
233
  return this.cachedAppCredential
234
234
  }
235
235
  this.cachedAppCredential =
236
- await this.secrets.getSecretJSON<OAuth2AppCredential>(
236
+ await this.secrets.getSecret<OAuth2AppCredential>(
237
237
  this.appCredentialSecretId
238
238
  )
239
239
  return this.cachedAppCredential